mocket

    A web framework for MoonBit.

    http
    server
    Download zip
    Author
    Version
    0.10.0
    License
    Apache-2.0
    Last updated
    1 hour ago
    Downloads
    2K

    #oboard/mocket

    Version GitHub Workflow Status (with event) License

    A web framework for MoonBit.

    #Quick Start

    async fn main {
    let app = @mocket.App()
    app.get("/", _ => "Hello, Mocket!")
    app.listen(":80")
    }

    Mocket supports both js and native backends.

    #JavaScript Backend

    Set the backend of MoonBit to js in Visual Studio Code

    Command: MoonBit: Select Backend -> js

    moon run src/example --target js

    #Native Backend

    Set the backend of MoonBit to native in Visual Studio Code

    Command: MoonBit: Select Backend -> native

    moon run src/example --target native

    Then visit http://localhost:4000

    #Usage

    Minimum Example: https://github.com/oboard/mocket_example

    🙌快来吧!🙌

    QQ 群号:949886784

    QQ 群

    ErrorHandler

    type ErrorHandler = (MocketEvent, Error) -> &Responder

    HttpHandler

    type HttpHandler = async (MocketEvent) -> &Responder

    Middleware

    type Middleware = async (MocketEvent, async () -> &Responder) -> &Responder

    MiddlewareNext

    type MiddlewareNext = async () -> &Responder

    WebSocketHandler

    type WebSocketHandler = (WebSocketEvent) -> Unit

    BodyReader

    pub(open) trait BodyReader {
    async fn from_request(req : HttpRequest) -> Self
    }

    impl BodyReader for Bytes
    impl BodyReader for Json

    Responder

    pub(open) trait Responder {
    fn options(Self, res : HttpResponse) -> Unit
    async fn output(Self, writer : &
    Writer
    ) -> Unit
    }

    impl Responder for String
    impl Responder for Bytes
    impl Responder for Json
    impl Responder for ToJson

    ServeStaticProvider

    pub(open) trait ServeStaticProvider {
    async fn get_meta(Self, id : StringView) -> StaticAssetMeta?
    async fn get_contents(Self, id : StringView) -> &Responder
    fn get_type(Self, ext : String) -> String?
    fn get_encodings(Self) -> Map[String, String]
    fn get_index_names(Self) -> Array[String]
    fn get_fallthrough(Self) -> Bool
    }

    A backend for Mocket::static_assets.

    Asset ids handed to the provider are virtual absolute paths rooted at the mount point: they always start with "/" and are already normalized, so "." / ".." segments can never escape the provider's root. Providers should join the id onto their root directly.

    ExecError

    pub suberror ExecError

    FormDataError

    pub suberror FormDataError {
    MissingContentType
    InvalidContentType(String)
    UnsupportedContentType(String)
    MissingBoundary
    }

    Errors raised while decoding a multipart/form-data request body.

    IOError

    pub suberror IOError

    NetworkError

    pub suberror NetworkError

    App

    #alias(Mocket)
    #alias(T)
    pub(all) struct App {
    base_path : String
    mappings : Map[(String, String), async (MocketEvent) -> &Responder]
    middlewares : Array[(String, async (MocketEvent, async () -> &Responder) -> &Responder)]
    static_routes : Map[String, Map[String, async (MocketEvent) -> &Responder]]
    dynamic_routes : Map[String, Array[(String, async (MocketEvent) -> &Responder)]]
    ws_static_routes : Map[String, (WebSocketEvent) -> Unit]
    ws_dynamic_routes : Array[(String, (WebSocketEvent) -> Unit)]
    ws_clients : Map[String, Unit]
    ws_channels : Map[String, Map[String, Unit]]
    ws_client_port : Map[String, Int]
    max_body_size : Int
    error_handler : (MocketEvent, Error) -> &Responder
    // private fields
    }

    App::App

    #alias(new, deprecated="Use `App()` instead")
    fn App::App(base_path? : String, max_body_size? : Int) -> App

    App::acl

    fn App::acl(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::all

    fn App::all(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::bind

    fn App::bind(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::checkin

    fn App::checkin(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::checkout

    fn App::checkout(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::connect

    fn App::connect(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::copy

    fn App::copy(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::delete

    fn App::delete(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::get

    fn App::get(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::group

    fn App::group(self : App, base_path : String, configure : (App) -> Unit) -> Unit

    App::head

    fn App::head(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::label

    fn App::label(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    fn App::link(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::listen

    async fn App::listen(self : App, address : String) -> Unit noraise

    App::lock

    fn App::lock(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::merge

    fn App::merge(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::mkactivity

    fn App::mkactivity(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::mkcalendar

    fn App::mkcalendar(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::mkcol

    fn App::mkcol(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::mkredirectref

    fn App::mkredirectref(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::mkworkspace

    fn App::mkworkspace(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::move_

    fn App::move_(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::on

    fn App::on(self : App, event : String, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::on_error

    fn App::on_error(self : App, handler : (MocketEvent, Error) -> &Responder) -> Unit

    App::options

    fn App::options(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::orderpatch

    fn App::orderpatch(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::patch

    fn App::patch(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::post

    fn App::post(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::pri

    fn App::pri(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::propfind

    fn App::propfind(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::proppatch

    fn App::proppatch(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::put

    fn App::put(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::query

    fn App::query(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::rebind

    fn App::rebind(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::report

    fn App::report(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::search

    fn App::search(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::serve

    #deprecated("use `Mocket::listen(address)` instead")
    async fn App::serve(self : App, port~ : Int) -> Unit noraise

    App::static_assets

    fn App::static_assets(self : App, path : String, provider : &ServeStaticProvider) -> Unit

    App::trace

    fn App::trace(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::unbind

    fn App::unbind(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::uncheckout

    fn App::uncheckout(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    fn App::unlink(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::unlock

    fn App::unlock(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::update

    fn App::update(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::updateredirectref

    fn App::updateredirectref(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::use_middleware

    fn App::use_middleware(self : App, middleware : async (MocketEvent, async () -> &Responder) -> &Responder, base_path? : String) -> Unit

    App::version_control

    fn App::version_control(self : App, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    App::ws

    fn App::ws(self : App, path : String, handler : (WebSocketEvent) -> Unit) -> Unit

    FormData

    pub(all) struct FormData {
    fields : Map[String, MultipartFormValue]
    response_boundary : String?
    }

    A parsed multipart/form-data request body.

    Each form field is indexed by name. Text fields and uploaded files both use MultipartFormValue; an upload has a filename, while a normal text field does not.

    FormData::fields

    fn FormData::fields(self : FormData) -> Map[String, MultipartFormValue]

    Returns all parsed form fields. For duplicate field names, the final value in the multipart body is retained.

    FormData::get

    fn FormData::get(self : FormData, name : String) -> MultipartFormValue?

    Looks up a form field or uploaded file by its field name.

    FormData::new

    fn FormData::new(fields : Map[String, MultipartFormValue]) -> FormData

    Creates multipart form data for use as a request body or response body.

    Html

    type Html

    impl Responder for Html

    HttpRequest

    pub(all) struct HttpRequest {
    http_method : String
    url : String
    query : String
    headers : Map[
    CaseInsensitiveString
    , StringView]
    reader : &
    Reader

    }

    HttpRequest::body

    async fn[T : BodyReader] HttpRequest::body(self : HttpRequest) -> T

    Decode the request body with T. On native HTTP requests this consumes the network body incrementally when the selected BodyReader supports it.
    fn HttpRequest::get_cookie(self : HttpRequest, name : String) ->
    Cookie
    ?

    Looks up a cookie from a request's Cookie header.

    HttpRequest::json

    HttpRequest::query

    fn HttpRequest::query(self : HttpRequest) -> Map[String, String]

    HttpResponse

    pub(all) struct HttpResponse {
    status_code : StatusCode
    headers : Map[
    CaseInsensitiveString
    , StringView]
    cookies : Array[
    Cookie
    ]
    body : &Responder?
    }

    HttpResponse::HttpResponse

    #alias(new, deprecated="Use `HttpResponse()` instead")
    fn HttpResponse::HttpResponse(status_code : StatusCode, headers? : Map[
    CaseInsensitiveString
    , StringView], cookies? : Array[
    Cookie
    ], body? : &Responder) -> HttpResponse

    HttpResponse::body

    fn HttpResponse::body(self : HttpResponse, body : &Responder) -> HttpResponse

    Sets the response body from any Responder.

    The body responder's default Content-Type is carried into this response only when no explicit "Content-Type" header was set on this response. Explicit response headers always take precedence.

    Only the default Content-Type is inferred. The responder's status, other headers, cookies, and any other responder effects are not merged, so self.status_code is preserved.
    fn HttpResponse::delete_cookie(self : HttpResponse, key : String) -> Unit

    HttpResponse::json

    fn HttpResponse::json(self : HttpResponse, obj : &ToJson) -> HttpResponse

    Sets a JSON response body.

    Infers Content-Type: application/json; charset=utf-8 under the same rule as HttpResponse::body: an explicit "Content-Type" header already present on this response takes precedence, and self.status_code is preserved.

    HttpResponse::read_body

    async fn[T : BodyReader] HttpResponse::read_body(self : HttpResponse) -> T

    fn HttpResponse::set_cookie(self : HttpResponse, cookie :
    Cookie
    ) -> Unit

    Adds an async HTTP runtime cookie as a Set-Cookie entry.

    HttpResponse::to_responder

    fn HttpResponse::to_responder(self : HttpResponse) -> &Responder

    MocketEvent

    pub(all) struct MocketEvent {
    req : HttpRequest
    res : HttpResponse
    params : Map[String, StringView]
    }

    MocketEvent::body

    async fn[T : BodyReader] MocketEvent::body(self : MocketEvent) -> T

    MultipartFormValue

    pub(all) struct MultipartFormValue {
    filename : String?
    content_type : String?
    data : BytesView
    }

    ResponseBuffer

    pub(all) struct ResponseBuffer {
    buffer :
    Buffer

    }

    Buffers output written through @io.Writer for backends that require a complete byte slice before they can send a response.

    ResponseBuffer::bytes

    fn ResponseBuffer::bytes(self : ResponseBuffer) -> Bytes

    ResponseBuffer::new

    StaticAssetMeta

    pub(all) struct StaticAssetMeta {
    asset_type : String?
    etag : String?
    mtime : Int64?
    path : String?
    size : Int64?
    encoding : String?
    }

    StaticAssetMeta::new

    fn StaticAssetMeta::new(asset_type? : String, etag? : String, mtime? : Int64, path? : String, size? : Int64, encoding? : String) -> StaticAssetMeta

    StatusCode

    pub(all) enum StatusCode {
    Continue
    SwitchingProtocols
    Processing
    EarlyHints
    OK
    Created
    Accepted
    NonAuthoritativeInfo
    NoContent
    ResetContent
    PartialContent
    MultiStatus
    AlreadyReported
    IMUsed
    MultipleChoices
    MovedPermanently
    Found
    SeeOther
    NotModified
    UseProxy
    TemporaryRedirect
    PermanentRedirect
    BadRequest
    Unauthorized
    PaymentRequired
    Forbidden
    NotFound
    MethodNotAllowed
    NotAcceptable
    ProxyAuthRequired
    RequestTimeout
    Conflict
    Gone
    LengthRequired
    PreconditionFailed
    RequestEntityTooLarge
    RequestUriTooLong
    UnsupportedMediaType
    RequestedRangeNotSatisfiable
    ExpectationFailed
    Teapot
    MisdirectedRequest
    UnprocessableEntity
    Locked
    FailedDependency
    TooEarly
    UpgradeRequired
    PreconditionRequired
    TooManyRequests
    RequestHeaderFieldsTooLarge
    UnavailableForLegalReasons
    InternalServerError
    NotImplemented
    BadGateway
    ServiceUnavailable
    GatewayTimeout
    HttpVersionNotSupported
    VariantAlsoNegotiates
    InsufficientStorage
    LoopDetected
    NotExtended
    NetworkAuthenticationRequired
    Custom(Int)
    } derive(Eq, ToJson)

    HTTP status codes as registered with IANA. See: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml

    StatusCode::from_int

    fn StatusCode::from_int(i : Int) -> StatusCode

    StatusCode::to_int

    fn StatusCode::to_int(self : StatusCode) -> Int

    WebSocketAggregatedMessage

    pub(all) enum WebSocketAggregatedMessage {
    Text(String)
    Binary(Bytes)
    Ping
    }

    WebSocketEvent

    pub(all) enum WebSocketEvent {
    Open(WebSocketPeer)
    Message(WebSocketPeer, WebSocketAggregatedMessage)
    Close(WebSocketPeer)
    }

    WebSocketPeer

    pub(all) struct WebSocketPeer {
    connection_id : String
    subscribed_channels : Array[String]
    }

    WebSocketPeer::binary

    fn WebSocketPeer::binary(self : WebSocketPeer, message : Bytes) -> Unit

    WebSocketPeer::pong

    fn WebSocketPeer::pong(self : WebSocketPeer) -> Unit

    WebSocketPeer::publish

    fn WebSocketPeer::publish(channel : String, message : String) -> Unit

    WebSocketPeer::subscribe

    fn WebSocketPeer::subscribe(self : WebSocketPeer, channel : String) -> Unit

    WebSocketPeer::text

    fn WebSocketPeer::text(self : WebSocketPeer, message : String) -> Unit

    WebSocketPeer::to_string

    fn WebSocketPeer::to_string(self : WebSocketPeer) -> String

    WebSocketPeer::unsubscribe

    fn WebSocketPeer::unsubscribe(self : WebSocketPeer, channel : String) -> Unit

    __ws_emit

    fn __ws_emit(event_type : Bytes, connection_id : Bytes, payload : Bytes) -> Unit

    dispatch_http

    async fn dispatch_http(mocket : App, http_method : String, url : String, headers : Map[
    CaseInsensitiveString
    , StringView], body : Bytes) -> HttpResponse

    dispatch_ws_event

    fn dispatch_ws_event(handler : (WebSocketEvent) -> Unit, peer : WebSocketPeer, event_type : String, payload : Bytes) -> Unit

    将 WS 事件类型字符串和 payload 转换为 WebSocketEvent 并调用 handler

    escape_html

    fn escape_html(s : String) -> String

    execute_middlewares

    async fn execute_middlewares(middlewares : Array[(String, async (MocketEvent, async () -> &Responder) -> &Responder)], event : MocketEvent, final_handler : async (MocketEvent) -> &Responder) -> &Responder

    form_encode

    fn form_encode(map : Map[String, String]) -> String

    handle_not_found

    fn handle_not_found() -> (async (MocketEvent) -> &Responder)

    html

    fn html(html : &Show) -> &Responder

    listen_ffi

    async fn listen_ffi(mocket : App, address : String) -> Unit noraise

    Listen and serve on address.

    The native listener enables SO_REUSEADDR (reuse_addr=true) so that a process can immediately rebind a port that a previous process left in TIME_WAIT. On macOS/BSD this has the side effect that a bind to a specific address may "steal" the specific interface from an existing wildcard bind (0.0.0.0), and a wildcard bind can bind to the remaining interfaces if a specific-interface bind already exists.

    new

    #deprecated("Use `App()` instead")
    fn new(base_path? : String, max_body_size? : Int) -> App

    parse_form_data

    fn parse_form_data(bytes : BytesView) -> Map[String, String]

    parse_query

    fn parse_query(query_string : StringView) -> Map[String, String]

    fn parse_request_cookie(cookie : StringView) -> Map[String,
    Cookie
    ]

    Parses the Cookie request header. Request cookies are name/value pairs; Set-Cookie attributes never apply to this header.

    register_ws_connection

    fn register_ws_connection(connection_id : String, text_sender : (String) -> Unit, binary_sender : (Bytes) -> Unit, pong_sender : () -> Unit) -> Unit

    register_ws_handler

    fn register_ws_handler(mocket : App, port : Int) -> Unit

    fn serialize_cookie(cookie :
    Cookie
    ) -> String

    Serializes an async HTTP cookie for non-native backends that need to write Set-Cookie themselves.

    serve_ffi

    async fn serve_ffi(mocket : App, port~ : Int) -> Unit noraise

    suspend

    async fn[T, E : Error] suspend(f : ((T) -> Unit, (E) -> Unit) -> Unit) -> T raise E

    suspend 会中断当前协程的运行。 suspend 会接受一个回调函数,并让这个回调函数来操作中断的协程

    text

    fn text(text : &Show) -> &Responder

    unregister_ws_connection

    fn unregister_ws_connection(connection_id : String) -> Unit

    url_decode

    fn url_decode(bytes : BytesView) -> String

    url_encode

    fn url_encode(s : String) -> String

    ws_pong

    fn ws_pong(id : String) -> Unit

    ws_publish

    fn ws_publish(channel : String, msg : String) -> Unit

    ws_send

    fn ws_send(id : String, msg : String) -> Unit

    ws_send_bytes

    fn ws_send_bytes(id : String, msg : Bytes) -> Unit

    ws_subscribe

    fn ws_subscribe(id : String, channel : String) -> Unit

    ws_unsubscribe

    fn ws_unsubscribe(id : String, channel : String) -> Unit