Every public type, function and method
The complete surface of the framework, grouped by package. Signatures come from the compiled interface; descriptions and examples from the source comments. Each item lists its parameters and return type.
@moonapi
The application object, response helpers, and the top-level API you build a service from.
Types
pub type ApiHandler = async (@ctx.Context) -> @http.Response
pub using @openapi {type ApiInfo}
pub using @security {type ApiKey}
pub using @security {type ApiKeyIn}
pub struct App { router : @route.Router layers : Array[&@mid.Layer] exception_handlers : Array[(@ctx.Context, Error) -> @http.Response?] security_schemes : Array[@security.DeclaredScheme] enforcers : Map[String, (@ctx.Context, @security.SecurityScopes, Int64) -> Result[@security.AuthenticatedUser, @http.Response]] status_handlers : Map[Int32, (@ctx.Context) -> @http.Response] mounts : Array[(String, Mount)] startup_hooks : Array[async (Map[String, Json]) -> Unit] shutdown_hooks : Array[async (Map[String, Json]) -> Unit] mut info : @openapi.ApiInfo mut clock : () -> Int64 mut deps : @di.Deps? redirect_slashes : Bool webhooks : @route.Router }
A moonapi application: routes and WebSocket routes, the layers around them, exception and per-status handlers, mounts, the security schemes the OpenAPI document surfaces (with their runtime enforcers), lifespan hooks, and the verification clock. Compiles to an ASGI application any server (mooncat) can run.
| Field | Type |
|---|---|
| router | @route.Router |
| layers | Array[&@mid.Layer] |
| exception_handlers | Array[(@ctx.Context, Error) -> @http.Response?] |
| security_schemes | Array[@security.DeclaredScheme] |
| enforcers | Map[String, (@ctx.Context, @security.SecurityScopes, Int64) -> Result[@security.AuthenticatedUser, @http.Response]] |
| status_handlers | Map[Int32, (@ctx.Context) -> @http.Response] |
| mounts | Array[(String, Mount)] |
| startup_hooks | Array[async (Map[String, Json]) -> Unit] |
| shutdown_hooks | Array[async (Map[String, Json]) -> Unit] |
| info mut | @openapi.ApiInfo |
| clock mut | () -> Int64 |
| deps mut | @di.Deps? |
| redirect_slashes | Bool |
| webhooks | @route.Router |
pub using @security {type AuthenticatedUser}
pub using @ctx {type BackgroundTasks}
pub using @security {type BasicAuth}
pub using @schema {type Constraint}
pub using @openapi {type Contact}
pub using @di {type Container}
pub using @ctx {type Context}
pub using @di {type Deps}
pub using @security {type DigestAuth}
pub using @socket {type Disconnected}
pub using @endpoint {type Endpoint}
pub using @status {type Events}
pub using @endpoint {type Example}
pub type ExceptionHandler = (@ctx.Context, Error) -> @http.Response?
pub using @openapi {type ExternalDocs}
pub using @schema {type Field}
pub type Hook = async (Map[String, Json]) -> Unit
A lifespan hook: it gets the lifespan state, where what it stores reaches every request as ctx.state().
pub type Hoop = async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply
pub using @ctx {type HttpBasicCredentials}
pub using @exceptions {type HttpException}
pub using @openapi {type License}
pub using @method {type Method}
pub type Middleware = async (@http.Request, async (@http.Request) -> @http.Response) -> @http.Response
A request-level middleware : the request and call_next, which runs the rest of the application, in; the response out. The response comes back whole, so a stream behind it is gathered first; a middleware that must keep streams streaming is a @mid.Layer.
pub using @security {type OAuth2CodeBearer}
pub using @security {type OAuth2PasswordBearer}
pub using @ctx {type OAuth2PasswordRequestForm}
pub using @schema {type ObjectSchema}
pub using @schema {type OpenApiVersion}
pub using @endpoint {type Param}
pub using @endpoint {type ParamLoc}
pub using @di {type Provider}
pub using @endpoint {type ResponseSpec}
pub using @route {type Router}
pub using @schema {type Schema}
pub using @di {type Scope}
pub using @security {type SecurityRequirement}
pub using @security {type SecurityScheme}
pub using @security {type SecurityScopes}
pub using @openapi {type Server}
pub using @status {type Stream}
pub type StreamHandler = async (@ctx.Context) -> @status.Stream
pub using @openapi {type Tag}
pub using @openapi {type Ui}
pub using @schema {type Unresolved}
pub type Url = (@route.Router) -> Unit
pub using @schema {type ValidationError}
pub using @socket {type WebSocket}
pub using @status {type Writer}
pub type WsHandler = async (@socket.WebSocket) -> Unit
pub using @socket {type WsMessage}
Constants & values
pub const HTTP_100_CONTINUE : Int32 = 100
pub const HTTP_101_SWITCHING_PROTOCOLS : Int32 = 101
pub const HTTP_102_PROCESSING : Int32 = 102
pub const HTTP_103_EARLY_HINTS : Int32 = 103
pub const HTTP_200_OK : Int32 = 200
pub const HTTP_201_CREATED : Int32 = 201
pub const HTTP_202_ACCEPTED : Int32 = 202
pub const HTTP_203_NON_AUTHORITATIVE_INFORMATION : Int32 = 203
pub const HTTP_204_NO_CONTENT : Int32 = 204
pub const HTTP_205_RESET_CONTENT : Int32 = 205
pub const HTTP_206_PARTIAL_CONTENT : Int32 = 206
pub const HTTP_207_MULTI_STATUS : Int32 = 207
pub const HTTP_208_ALREADY_REPORTED : Int32 = 208
pub const HTTP_226_IM_USED : Int32 = 226
pub const HTTP_300_MULTIPLE_CHOICES : Int32 = 300
pub const HTTP_301_MOVED_PERMANENTLY : Int32 = 301
pub const HTTP_302_FOUND : Int32 = 302
pub const HTTP_303_SEE_OTHER : Int32 = 303
pub const HTTP_304_NOT_MODIFIED : Int32 = 304
pub const HTTP_305_USE_PROXY : Int32 = 305
pub const HTTP_306_RESERVED : Int32 = 306
pub const HTTP_307_TEMPORARY_REDIRECT : Int32 = 307
pub const HTTP_308_PERMANENT_REDIRECT : Int32 = 308
pub const HTTP_400_BAD_REQUEST : Int32 = 400
pub const HTTP_401_UNAUTHORIZED : Int32 = 401
pub const HTTP_402_PAYMENT_REQUIRED : Int32 = 402
pub const HTTP_403_FORBIDDEN : Int32 = 403
pub const HTTP_404_NOT_FOUND : Int32 = 404
pub const HTTP_405_METHOD_NOT_ALLOWED : Int32 = 405
pub const HTTP_406_NOT_ACCEPTABLE : Int32 = 406
pub const HTTP_407_PROXY_AUTHENTICATION_REQUIRED : Int32 = 407
pub const HTTP_408_REQUEST_TIMEOUT : Int32 = 408
pub const HTTP_409_CONFLICT : Int32 = 409
pub const HTTP_410_GONE : Int32 = 410
pub const HTTP_411_LENGTH_REQUIRED : Int32 = 411
pub const HTTP_412_PRECONDITION_FAILED : Int32 = 412
pub const HTTP_413_REQUEST_ENTITY_TOO_LARGE : Int32 = 413
pub const HTTP_414_REQUEST_URI_TOO_LONG : Int32 = 414
pub const HTTP_415_UNSUPPORTED_MEDIA_TYPE : Int32 = 415
pub const HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE : Int32 = 416
pub const HTTP_417_EXPECTATION_FAILED : Int32 = 417
pub const HTTP_418_IM_A_TEAPOT : Int32 = 418
pub const HTTP_421_MISDIRECTED_REQUEST : Int32 = 421
pub const HTTP_422_UNPROCESSABLE_ENTITY : Int32 = 422
pub const HTTP_423_LOCKED : Int32 = 423
pub const HTTP_424_FAILED_DEPENDENCY : Int32 = 424
pub const HTTP_425_TOO_EARLY : Int32 = 425
pub const HTTP_426_UPGRADE_REQUIRED : Int32 = 426
pub const HTTP_428_PRECONDITION_REQUIRED : Int32 = 428
pub const HTTP_429_TOO_MANY_REQUESTS : Int32 = 429
pub const HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE : Int32 = 431
pub const HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS : Int32 = 451
pub const HTTP_500_INTERNAL_SERVER_ERROR : Int32 = 500
pub const HTTP_501_NOT_IMPLEMENTED : Int32 = 501
pub const HTTP_502_BAD_GATEWAY : Int32 = 502
pub const HTTP_503_SERVICE_UNAVAILABLE : Int32 = 503
pub const HTTP_504_GATEWAY_TIMEOUT : Int32 = 504
pub const HTTP_505_HTTP_VERSION_NOT_SUPPORTED : Int32 = 505
pub const HTTP_506_VARIANT_ALSO_NEGOTIATES : Int32 = 506
pub const HTTP_507_INSUFFICIENT_STORAGE : Int32 = 507
pub const HTTP_508_LOOP_DETECTED : Int32 = 508
pub const HTTP_510_NOT_EXTENDED : Int32 = 510
pub const HTTP_511_NETWORK_AUTHENTICATION_REQUIRED : Int32 = 511
pub let query_limits : @moonurl.Limits
pub const WS_1000_NORMAL_CLOSURE : Int32 = 1000
pub const WS_1001_GOING_AWAY : Int32 = 1001
pub const WS_1002_PROTOCOL_ERROR : Int32 = 1002
pub const WS_1003_UNSUPPORTED_DATA : Int32 = 1003
pub const WS_1005_NO_STATUS_RCVD : Int32 = 1005
pub const WS_1006_ABNORMAL_CLOSURE : Int32 = 1006
pub const WS_1007_INVALID_FRAME_PAYLOAD_DATA : Int32 = 1007
pub const WS_1008_POLICY_VIOLATION : Int32 = 1008
pub const WS_1009_MESSAGE_TOO_BIG : Int32 = 1009
pub const WS_1010_MANDATORY_EXT : Int32 = 1010
pub const WS_1011_INTERNAL_ERROR : Int32 = 1011
pub const WS_1012_SERVICE_RESTART : Int32 = 1012
pub const WS_1013_TRY_AGAIN_LATER : Int32 = 1013
pub const WS_1014_BAD_GATEWAY : Int32 = 1014
pub const WS_1015_TLS_HANDSHAKE : Int32 = 1015
Functions
pub fn check_constraints(Json, Array[@schema.Constraint], Array[String], Array[@schema.ValidationError]) -> Unit
| Parameter | Type | Default |
|---|---|---|
| type only | Json | required |
| type only | Array[@schema.Constraint] | required |
| type only | Array[String] | required |
| type only | Array[@schema.ValidationError] | required |
Returns Unit
pub fn create_access_token(String, String, Int64, scopes? : Array[String], expires_in_secs? : Int64, extra? : Map[String, Json], wins? : @jwt.Wins, clash? : @jwt.OnClash[Map[String, Json]]) -> String
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | String | required |
| type only | Int64 | required |
| scopes | Array[String] | optional |
| expires_in_secs | Int64 | optional |
| extra | Map[String, Json] | optional |
| wins | @jwt.Wins | optional |
| clash | @jwt.OnClash[Map[String, Json]] | optional |
Returns String
pub fn data_response(String, filename? : String, status? : Int32, inline? : Bool) -> @http.Response?
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| filename | String | optional |
| status | Int32 | optional |
| inline | Bool | optional |
Returns @http.Response?
pub fn data_url(Bytes, media_type? : String) -> String
| Parameter | Type | Default |
|---|---|---|
| type only | Bytes | required |
| media_type | String | optional |
Returns String
pub fn delete_cookie(@http.Response, String, path? : String?, domain? : String, secure? : Bool, http_only? : Bool, same_site? : @cookie.SameSite?) -> @http.Response
| Parameter | Type | Default |
|---|---|---|
| type only | @http.Response | required |
| type only | String | required |
| path | String? | optional |
| domain | String | optional |
| secure | Bool | optional |
| http_only | Bool | optional |
| same_site | @cookie.SameSite? | optional |
Returns @http.Response
pub fn file_response(Bytes, filename? : String, media_type? : String, status? : Int32, inline? : Bool) -> @http.Response
| Parameter | Type | Default |
|---|---|---|
| type only | Bytes | required |
| filename | String | optional |
| media_type | String | optional |
| status | Int32 | optional |
| inline | Bool | optional |
Returns @http.Response
pub fn filter_response(@schema.Schema, Json) -> Result[Json, Array[@schema.ValidationError]]
| Parameter | Type | Default |
|---|---|---|
| type only | @schema.Schema | required |
| type only | Json | required |
Returns Result[Json, Array[@schema.ValidationError]]
pub fn group(String, Array[(@route.Router) -> Unit], tags? : Array[String], security? : Array[@security.SecurityRequirement], dependencies? : Array[String], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> (@route.Router) -> Unit
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | Array[(@route.Router) -> Unit] | required |
| tags | Array[String] | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns (@route.Router) -> Unit
pub fn html(Int32, String) -> @http.Response
| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | String | required |
Returns @http.Response
pub fn http_error(Int32, String, headers? : Array[(String, String)]) -> @exceptions.HttpException
| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | String | required |
| headers | Array[(String, String)] | optional |
Returns @exceptions.HttpException
pub fn json(Int32, Json) -> @http.Response
| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | Json | required |
Returns @http.Response
pub fn json_model(Int32, @schema.Schema, Json) -> @http.Response
| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | @schema.Schema | required |
| type only | Json | required |
Returns @http.Response
pub fn parse_basic_auth(String) -> @ctx.HttpBasicCredentials?
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns @ctx.HttpBasicCredentials?
pub fn path(String, async (@ctx.Context) -> @http.Response, methods? : Array[@method.Method], name? : String) -> (@route.Router) -> Unit
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| methods | Array[@method.Method] | optional |
| name | String | optional |
Returns (@route.Router) -> Unit
pub fn redirect(String, status? : Int32) -> @http.Response
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| status | Int32 | optional |
Returns @http.Response
pub fn redoc_ui(spec_url? : String, title? : String, js_url? : String, telemetry? : Bool) -> String
| Parameter | Type | Default |
|---|---|---|
| spec_url | String | optional |
| title | String | optional |
| js_url | String | optional |
| telemetry | Bool | optional |
Returns String
pub fn scalar_ui(spec_url? : String, title? : String, js_url? : String, extra? : Map[String, Json]) -> String
| Parameter | Type | Default |
|---|---|---|
| spec_url | String | optional |
| title | String | optional |
| js_url | String | optional |
| extra | Map[String, Json] | optional |
Returns String
pub fn set_cookie(@http.Response, String, String, max_age? : Int32, expires? : @moondate.Moment, path? : String?, domain? : String, secure? : Bool, http_only? : Bool, same_site? : @cookie.SameSite?) -> @http.Response
| Parameter | Type | Default |
|---|---|---|
| type only | @http.Response | required |
| type only | String | required |
| type only | String | required |
| max_age | Int32 | optional |
| expires | @moondate.Moment | optional |
| path | String? | optional |
| domain | String | optional |
| secure | Bool | optional |
| http_only | Bool | optional |
| same_site | @cookie.SameSite? | optional |
Returns @http.Response
pub fn sse(async (@status.Events) -> Unit, status? : Int32, headers? : Array[(String, String)], space? : Bool, wins? : @jwt.Wins, clash? : @jwt.OnClash[Array[(String, String)]]) -> @status.Stream
| Parameter | Type | Default |
|---|---|---|
| type only | async (@status.Events) -> Unit | required |
| status | Int32 | optional |
| headers | Array[(String, String)] | optional |
| space | Bool | optional |
| wins | @jwt.Wins | optional |
| clash | @jwt.OnClash[Array[(String, String)]] | optional |
Returns @status.Stream
pub fn swagger_redirect(js_url? : String) -> String
| Parameter | Type | Default |
|---|---|---|
| js_url | String | optional |
Returns String
pub fn swagger_ui(spec_url? : String, title? : String, js_url? : String, css_url? : String, oauth2_redirect_url? : String, init_oauth? : Json, extra? : Map[String, Json]) -> String
| Parameter | Type | Default |
|---|---|---|
| spec_url | String | optional |
| title | String | optional |
| js_url | String | optional |
| css_url | String | optional |
| oauth2_redirect_url | String | optional |
| init_oauth | Json | optional |
| extra | Map[String, Json] | optional |
Returns String
pub fn text(Int32, String) -> @http.Response
| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | String | required |
Returns @http.Response
pub fn token_response(String) -> @http.Response
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns @http.Response
pub fn unprocessable(Array[@schema.ValidationError]) -> @http.Response
| Parameter | Type | Default |
|---|---|---|
| type only | Array[@schema.ValidationError] | required |
Returns @http.Response
pub fn validate_schema(@schema.Schema, Json, Array[String], Array[@schema.ValidationError]) -> Unit
| Parameter | Type | Default |
|---|---|---|
| type only | @schema.Schema | required |
| type only | Json | required |
| type only | Array[String] | required |
| type only | Array[@schema.ValidationError] | required |
Returns Unit
pub fn validation_error_body(Array[@schema.ValidationError]) -> Json
| Parameter | Type | Default |
|---|---|---|
| type only | Array[@schema.ValidationError] | required |
Returns Json
pub fn view(String, &@route.View, name? : String) -> (@route.Router) -> Unit
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | &@route.View | required |
| name | String | optional |
Returns (@route.Router) -> Unit
pub fn websocket(String, async (@socket.WebSocket) -> Unit, name? : String) -> (@route.Router) -> Unit
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@socket.WebSocket) -> Unit | required |
| name | String | optional |
Returns (@route.Router) -> Unit
pub fn with_constraints(Json, Array[@schema.Constraint], @schema.OpenApiVersion) -> Json
| Parameter | Type | Default |
|---|---|---|
| type only | Json | required |
| type only | Array[@schema.Constraint] | required |
| type only | @schema.OpenApiVersion | required |
Returns Json
Methods on App
pub fn App::add_security_scheme(Self, String, @security.SecurityScheme, description? : String) -> Unit
Declare a security scheme under name, surfaced in the emitted OpenAPI document (components/securitySchemes in 3.x, securityDefinitions in Swagger 2.0) so the generated spec describes how to authenticate. description is the prose shown beside it in the documentation UI.
This declares only. A route naming this scheme in its security is documented as protected and left unguarded, exactly as a scheme that no path operation depends on is — the secure_* functions are the ones that wire an enforcer.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | @security.SecurityScheme | required |
| description | String | optional |
Returns Unit
pub fn App::add_status_handler(Self, Int32, (@ctx.Context) -> @http.Response) -> Unit
Register a per-status exception handler keyed by an HTTP status code). Whenever an error path yields status — a routing 404 / 405, or a raised HttpException (or the fallback 500) — the handler's response replaces the default, so an app can serve a custom error page. Successful handler returns are never rewritten.
| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | (@ctx.Context) -> @http.Response | required |
Returns Unit
pub fn App::delete(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[@route.Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register a DELETE route. A shorthand for route(Delete, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[@route.Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::depends(Self, @di.Deps) -> Unit
Give the app the dependency container its routes resolve their declared dependencies through the application supplies). The container's value type is erased on the way in, because a route-level dependency runs for its effect and its value is never handed to the handler — the same thing dependencies=[...] does with the values it builds.
A route that declares a dependency the container does not provide is answered with a 500: the setup the route promised did not happen, and running the handler as though it had is worse than saying so.
| Parameter | Type | Default |
|---|---|---|
| type only | @di.Deps | required |
Returns Unit
pub fn App::describe(Self, title? : String, summary? : String, api_version? : String, description? : String, terms_of_service? : String, contact? : @openapi.Contact?, license? : @openapi.License?, servers? : Array[@openapi.Server], tags? : Array[@openapi.Tag], external_docs? : @openapi.ExternalDocs?) -> Unit
Set what the OpenAPI document says about this API summary=…, description=…, contact=…, license_info=…, servers=…, openapi_tags=…, openapi_external_docs=…)). App::openapi and the /openapi.json route enable_docs` registers both read it, so the document a client fetches and the one a test builds cannot describe different APIs. An argument left out keeps what was set before.
| Parameter | Type | Default |
|---|---|---|
| title | String | optional |
| summary | String | optional |
| api_version | String | optional |
| description | String | optional |
| terms_of_service | String | optional |
| contact | @openapi.Contact? | optional |
| license | @openapi.License? | optional |
| servers | Array[@openapi.Server] | optional |
| tags | Array[@openapi.Tag] | optional |
| external_docs | @openapi.ExternalDocs? | optional |
Returns Unit
pub fn App::enable_docs(Self, openapi_url? : String?, docs_url? : String?, redoc_url? : String?, version? : @schema.OpenApiVersion, ui? : @openapi.Ui, oauth2_redirect_url? : String?, init_oauth? : Json, ui_extra? : Map[String, Json], root_path_in_servers? : Bool) -> Unit
Serve the app's own documentation: the OpenAPI document at openapi_url, an interactive reference at docs_url, and ReDoc at redoc_url. Pass None for any of them to leave it off. The routes are kept out of the document they serve, so enabling docs does not change the spec a client reads.
ui picks the reader at docs_url. With Swagger, oauth2_redirect_url is where an OAuth2 flow started from the page returns to, and init_oauth prefills it ; ui_extra is merged over the reader's own settings either way.
Behind a proxy that mounts the app under a prefix, the server reports that prefix as the ASGI root_path. The pages then fetch the document from under it, and with root_path_in_servers the document names it as its first server, so a call tried out from the page goes where the app actually is.
It is a call rather than a default because registering routes behind the app's back would surprise anyone mounting this app under a prefix.
| Parameter | Type | Default |
|---|---|---|
| openapi_url | String? | optional |
| docs_url | String? | optional |
| redoc_url | String? | optional |
| version | @schema.OpenApiVersion | optional |
| ui | @openapi.Ui | optional |
| oauth2_redirect_url | String? | optional |
| init_oauth | Json | optional |
| ui_extra | Map[String, Json] | optional |
| root_path_in_servers | Bool | optional |
Returns Unit
pub fn App::exception_handler(Self, (@ctx.Context, Error) -> @http.Response?) -> Unit
Register an exception handler. On a raised error the handlers are tried in registration order; the first to return Some(response) wins. An unhandled error falls through to the built-in mapping — an HttpException becomes its own status / detail, anything else a 500.
| Parameter | Type | Default |
|---|---|---|
| type only | (@ctx.Context, Error) -> @http.Response? | required |
Returns Unit
pub fn App::get(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[@route.Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register a GET route. A shorthand for route(Get, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[@route.Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub async fn App::handle(Self, @http.Request) -> @http.Response
Run request through the app in-process and return the response, the way a server would see it answered: the same ASGI path, layers included . A streamed response comes back with its body joined.
async test {
let app = @moonapi.App::new()
app.get("/users/{id}", ctx => {
@moonapi.text(200, "user " + ctx.param("id").unwrap())
})
let reply = app.handle({
http_method: "GET",
path: "/users/42",
query_string: b"",
headers: [],
body: b"",
})
assert_eq(reply.body, b"user 42")
}| Parameter | Type | Default |
|---|---|---|
| type only | @http.Request | required |
Returns @http.Response
pub fn App::head(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[@route.Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register a HEAD route. A shorthand for route(Head, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[@route.Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::include_router(Self, @route.Router, prefix? : String, tags? : Array[String], security? : Array[@security.SecurityRequirement], dependencies? : Array[String], responses? : Array[@endpoint.ResponseSpec], deprecated? : Bool, include_in_schema? : Bool, hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Fold router's routes into this app ( include_router, and the same name — include is a reserved word). Each is registered under prefix and becomes one of the app's own routes, with the arguments given here reaching every one of them as Router::include_router describes.
| Parameter | Type | Default |
|---|---|---|
| type only | @route.Router | required |
| prefix | String | optional |
| tags | Array[String] | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| deprecated | Bool | optional |
| include_in_schema | Bool | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::layer(Self, &@mid.Layer) -> Unit
Wrap the application in layer, a moonasgi ASGI middleware add_middleware): moonasgi's Cors, Gzip, TrustedHosts, HttpsRedirect and ServerErrors, or one of your own. The first registered is the outermost, layers and middleware alike, and they wrap mounted applications too.
| Parameter | Type | Default |
|---|---|---|
| type only | &@mid.Layer | required |
Returns Unit
pub fn App::middleware(Self, async (@http.Request, async (@http.Request) -> @http.Response) -> @http.Response) -> Unit
Add a request-level middleware , placed among the layers in registration order.
| Parameter | Type | Default |
|---|---|---|
| type only | async (@http.Request, async (@http.Request) -> @http.Response) -> @http.Response | required |
Returns Unit
pub fn App::mount(Self, String, Self) -> Unit
Mount a sub-application under prefix . A request whose path lies under prefix is served by subapp, with the prefix moved from path to root_path (its own layers, security and background tasks apply), and the sub-app's routes appear under prefix in the merged OpenAPI document with its security schemes folded into the parent's.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns Unit
pub fn App::mount_asgi(Self, String, async (@spec.Scope, async () -> @spec.Event, async (@spec.Event) -> Unit) -> Unit) -> Unit
Mount any ASGI application under prefix app.mount("/static", StaticFiles(...))). A request under prefix reaches app with the prefix moved from path to root_path, exactly as for a sub-app.
It is not a moonapi application, so it contributes nothing to the OpenAPI document and has no lifespan of its own to run — the app only routes to it. Mounts are tried in registration order, whichever kind they are.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@spec.Scope, async () -> @spec.Event, async (@spec.Event) -> Unit) -> Unit | required |
Returns Unit
pub fn App::new(redirect_slashes? : Bool) -> Self
Create an empty application. The verification clock defaults to 0 (Unix epoch); a server sets a real one with App::set_clock, and tests inject a fixed time so token expiry is deterministic.
redirect_slashes answers a path that matches no route, but would with its trailing slash added or removed, with a 307 to that other path, the query kept . / itself is never redirected, nor is a WebSocket connection.
async test {
let app = @moonapi.App::new()
app.get("/", _ctx => @moonapi.text(200, "Hello"))
let reply = app.handle({
http_method: "GET",
path: "/",
query_string: b"",
headers: [],
body: b"",
})
assert_eq(reply.status, 200)
}| Parameter | Type | Default |
|---|---|---|
| redirect_slashes | Bool | optional |
Returns Self
pub fn App::on_shutdown(Self, async (Map[String, Json]) -> Unit) -> Unit
Run hook when the server shuts down, after the last request has been served on_event("shutdown")). Hooks run in reverse registration order, so a resource is released before whatever it was opened from. A hook that raises does not stop the others — shutdown reports the first failure once the rest have run.
| Parameter | Type | Default |
|---|---|---|
| type only | async (Map[String, Json]) -> Unit | required |
Returns Unit
pub fn App::on_startup(Self, async (Map[String, Json]) -> Unit) -> Unit
Run hook when the server starts, before it accepts the first request on_event("startup")). Hooks run in the order they were registered; one that raises aborts startup, and the server is told why.
| Parameter | Type | Default |
|---|---|---|
| type only | async (Map[String, Json]) -> Unit | required |
Returns Unit
pub fn App::openapi(Self, version? : @schema.OpenApiVersion, title? : String, summary? : String, api_version? : String, description? : String, terms_of_service? : String, contact? : @openapi.Contact?, license? : @openapi.License?, servers? : Array[@openapi.Server], tags? : Array[@openapi.Tag], external_docs? : @openapi.ExternalDocs?) -> Json
Build the app's OpenAPI document as a Json value, walking the registered routes — this app's and every mounted sub-app's, each under its prefix — into paths, methods and operations. version picks the dialect: Swagger 2.0, OpenAPI 3.0.3 or 3.1.0 off the identical routes. Routes registered with include_in_schema=false are left out.
The webhooks go under webhooks, which only 3.1 has; callbacks go under their operation in both 3.x dialects. Swagger 2.0 can express neither and leaves them out. The named arguments override what App::describe set, for this one document.
| Parameter | Type | Default |
|---|---|---|
| version | @schema.OpenApiVersion | optional |
| title | String | optional |
| summary | String | optional |
| api_version | String | optional |
| description | String | optional |
| terms_of_service | String | optional |
| contact | @openapi.Contact? | optional |
| license | @openapi.License? | optional |
| servers | Array[@openapi.Server] | optional |
| tags | Array[@openapi.Tag] | optional |
| external_docs | @openapi.ExternalDocs? | optional |
Returns Json
pub fn App::openapi_json(Self, version? : @schema.OpenApiVersion) -> String
The app's OpenAPI / Swagger document for version, stringified.
test {
let app = @moonapi.App::new()
app.get("/ping", _ctx => @moonapi.text(200, "pong"), summary="health check")
let doc = app.openapi_json()
assert_true(doc.contains("\"openapi\": \"3.1.0\""))
assert_true(doc.contains("\"/ping\""))
}| Parameter | Type | Default |
|---|---|---|
| version | @schema.OpenApiVersion | optional |
Returns String
pub fn App::options(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[@route.Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register a OPTIONS route. A shorthand for route(Options, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[@route.Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::patch(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[@route.Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register a PATCH route. A shorthand for route(Patch, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[@route.Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::post(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[@route.Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register a POST route. A shorthand for route(Post, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[@route.Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::put(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[@route.Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register a PUT route. A shorthand for route(Put, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[@route.Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::route(Self, @method.Method, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[@route.Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register a route for an explicit method. An optional endpoint descriptor makes the route fully typed (its parameters, request body, and responses surface in the OpenAPI document and drive validation); security attaches per-operation requirements (emitted as OpenAPI security and enforced before the handler when their scheme has an enforcer); dependencies names provider keys resolved through the app's container (App::depends) before the handler and torn down after it, whatever the handler did.
The rest describe the operation: summary and description are its prose, operation_id the stable handle client generators name their method after, status_code the status its success response is documented under, responses further documented responses, name the handle App::url_for resolves, openapi_extra a fragment merged over the generated operation object, and callbacks the requests this operation makes back to its caller, written as routes whose paths are runtime expressions — the same keyword arguments path operations take. hoops wrap this one route, inside any its routers put around it.
| Parameter | Type | Default |
|---|---|---|
| type only | @method.Method | required |
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[@route.Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::route_stream(Self, @method.Method, String, async (@ctx.Context) -> @status.Stream, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[@route.Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register a streaming route StreamingResponse). The handler's chunks reach the client as separate body events, so a long or open-ended reply starts arriving before it is finished.
A stream is only streamed as far as the app can honestly keep it one: a middleware that rewrites the body — gzip does — collapses the reply to a single chunk. Everything else about the route is ordinary; it documents, validates and enforces security exactly as route does.
| Parameter | Type | Default |
|---|---|---|
| type only | @method.Method | required |
| type only | String | required |
| type only | async (@ctx.Context) -> @status.Stream | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[@route.Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::secure_api_key(Self, String, @security.ApiKey, description? : String, auto_error? : Bool) -> Unit
Declare an API-key scheme under name and wire it as a runtime enforcer Security(APIKeyHeader(name=...))). The scheme appears in the document as apiKey in the header, query or cookie the key names, and a route requiring name is refused with 403 unless it presents a key the scheme accepts.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | @security.ApiKey | required |
| description | String | optional |
| auto_error | Bool | optional |
Returns Unit
pub fn App::secure_basic(Self, String, @security.BasicAuth, description? : String, auto_error? : Bool) -> Unit
Declare an HTTP Basic scheme under name and wire it as a runtime enforcer . A route requiring name is refused with 401 and a Basic challenge unless it presents credentials the scheme accepts.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | @security.BasicAuth | required |
| description | String | optional |
| auto_error | Bool | optional |
Returns Unit
pub fn App::secure_bearer(Self, String, String, bearer_format? : String, description? : String, auto_error? : Bool) -> Unit
Declare a plain HTTP bearer scheme under name and wire it as a runtime enforcer . The token is verified as an HS256 JWT against secret at the app clock's time, and the route's required scopes are checked against the token's — the same guard the OAuth2 flows use, without an OAuth2 flow to advertise.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | String | required |
| bearer_format | String | optional |
| description | String | optional |
| auto_error | Bool | optional |
Returns Unit
pub fn App::secure_digest(Self, String, @security.DigestAuth, description? : String, auto_error? : Bool) -> Unit
Declare an HTTP Digest scheme under name and wire it as a runtime enforcer . A route requiring name is refused with 403 unless it presents a Digest credential the scheme accepts.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | @security.DigestAuth | required |
| description | String | optional |
| auto_error | Bool | optional |
Returns Unit
pub fn App::secure_oauth2(Self, String, @security.OAuth2PasswordBearer, scopes? : Array[(String, String)], description? : String, auto_error? : Bool) -> Unit
Declare an OAuth2 password-bearer scheme under name and wire it as a runtime enforcer. Like add_security_scheme it surfaces the scheme in the OpenAPI document (with the advertised scopes and description), and additionally registers the guard a route names in its security: the app pulls the bearer token, verifies it against bearer's secret at the app clock's time, and checks the route's required scopes — returning 401/403 before the handler runs.
auto_error=false admits the request instead of refusing it every security class takes, whose dependency then yields None and leaves the decision to the route).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | @security.OAuth2PasswordBearer | required |
| scopes | Array[(String, String)] | optional |
| description | String | optional |
| auto_error | Bool | optional |
Returns Unit
pub fn App::secure_oauth2_code(Self, String, @security.OAuth2CodeBearer, scopes? : Array[(String, String)], description? : String, auto_error? : Bool) -> Unit
Declare an OAuth2 authorization-code scheme under name and wire it as a runtime enforcer . The document describes the browser redirect and token endpoints and the advertised scopes; the guard verifies the presented bearer token exactly as the password flow's does, since by the time a request arrives the two flows have produced the same credential.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | @security.OAuth2CodeBearer | required |
| scopes | Array[(String, String)] | optional |
| description | String | optional |
| auto_error | Bool | optional |
Returns Unit
pub fn App::secure_openid(Self, String, String, String, description? : String, auto_error? : Bool) -> Unit
Declare an OpenID Connect scheme under name and wire it as a runtime enforcer . url is the discovery document a client reads every other parameter from; secret is what the ID token presented as a bearer credential is verified against.
Swagger 2.0 has no openIdConnect type, so this scheme is absent from a 2.0 document rather than described as something it is not.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | String | required |
| type only | String | required |
| description | String | optional |
| auto_error | Bool | optional |
Returns Unit
pub fn App::set_clock(Self, () -> Int64) -> Unit
Set the clock the app reads to verify token expiry when enforcing route security (Unix seconds). A native server passes the wall clock; a test passes a fixed function so expiry is deterministic.
| Parameter | Type | Default |
|---|---|---|
| type only | () -> Int64 | required |
Returns Unit
pub fn App::stream(Self, String, async (@ctx.Context) -> @status.Stream, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[@route.Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register a streaming GET route — the verb a stream is nearly always read over, and what an SSE endpoint is. A shorthand for route_stream(Get, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @status.Stream | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[@route.Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::to_asgi(Self) -> async (@spec.Scope, async () -> @spec.Event, async (@spec.Event) -> Unit) -> Unit
Compile the app to an ASGI application a server can run: the layers around the router, in registration order with the first outermost.
Returns async (@spec.Scope, async () -> @spec.Event, async (@spec.Event) -> Unit) -> Unit
pub fn App::trace(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[@route.Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register a TRACE route. A shorthand for route(Trace, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[@route.Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::url_for(Self, String, params? : Map[String, String]) -> String?
The path of the route registered under name, with its parameters filled from params . Mounted sub-applications are searched too, so what comes back already carries the mount prefix — the path a client would call, not the one the sub-app knows itself by.
None when nothing is registered under that name, or when params is missing one the path needs or holds one its convertor refuses; only a path parameter takes a /.
test {
let app = @moonapi.App::new()
app.get("/items/{id}", _ctx => @moonapi.text(200, "item"), name="get_item")
assert_eq(
app.url_for("get_item", params=Map([("id", "77")])),
Some("/items/77"),
)
}| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| params | Map[String, String] | optional |
Returns String?
pub fn App::urls(Self, Array[(@route.Router) -> Unit]) -> Unit
Register a route table; see Router::urls.
| Parameter | Type | Default |
|---|---|---|
| type only | Array[(@route.Router) -> Unit] | required |
Returns Unit
pub fn App::view(Self, String, &@route.View, name? : String, tags? : Array[String], security? : Array[@security.SecurityRequirement], dependencies? : Array[String], deprecated? : Bool, include_in_schema? : Bool, hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply]) -> Unit
Register the methods view answers at path; see Router::view.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | &@route.View | required |
| name | String | optional |
| tags | Array[String] | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| deprecated | Bool | optional |
| include_in_schema | Bool | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> @route.Reply) -> @route.Reply] | optional |
Returns Unit
pub fn App::websocket(Self, String, async (@socket.WebSocket) -> Unit, name? : String, security? : Array[@security.SecurityRequirement], dependencies? : Array[String]) -> Unit
Register a WebSocket route . The path is a template with the same parameters and convertors as an HTTP route's.
security is enforced and dependencies resolved before the handler is called. A refusal declines the handshake with the response an HTTP route would have answered — through ASGI's websocket.http.response extension where the server offers it, and with close code 1008 otherwise. The dependencies are torn down when the handler returns. name is the handle App::url_for resolves.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@socket.WebSocket) -> Unit | required |
| name | String | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
Returns Unit
@ctx
The per-request context: path, query, header and cookie extraction, body parsing, and state.
Types
pub struct BackgroundTasks { // private fields }
A queue of deferred tasks. A handler adds to ctx.background; the app runs the queue in the order tasks were added, after the response is sent and within the same request.
pub using @moonmime {type Form}
pub using @moonmime {type Limits}
pub using @moonmime {type Upload}
Functions
pub fn parse_basic_auth(String) -> HttpBasicCredentials?
Parse an HTTP Basic Authorization header value into credentials , or None. Matches the Basic scheme case-insensitively (RFC 7617), base64-decodes the rest, and splits on the first colon so a password may itself contain colons.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns HttpBasicCredentials?
pub fn split_scopes(String) -> Array[String]
Split a space-delimited scope string into its scopes, dropping empty runs — the OAuth2 scope form field is one string like "read write".
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns Array[String]
Methods on BackgroundTasks
pub fn BackgroundTasks::add_task(Self, async () -> Unit) -> Unit
Enqueue a task to run after the response is sent .
| Parameter | Type | Default |
|---|---|---|
| type only | async () -> Unit | required |
Returns Unit
pub fn BackgroundTasks::length(Self) -> Int32
How many tasks are queued.
Returns Int32
pub fn BackgroundTasks::new() -> Self
An empty task queue.
Returns Self
pub async fn BackgroundTasks::run(Self) -> Unit
Run every queued task in order, each after the previous returns, then clear the queue. A task that raises stops the ones after it and the error goes to the caller, as in .
Returns Unit
Methods on Context
pub fn Context::api_key_cookie(Self, String) -> String?
The API key carried in the cookie name , or None.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns String?
pub fn Context::api_key_header(Self, String) -> String?
The API key carried in the request header name , or None. Header names are matched against the request's lower-cased headers.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns String?
pub fn Context::api_key_query(Self, String) -> String?
The API key carried in the query parameter name , or None.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns String?
pub fn Context::bearer_token(Self) -> String?
Pull the bearer token out of the Authorization: Bearer <token> header, None if the header is absent or isn't a bearer credential. The scheme name is matched case-insensitively, as RFC 6750 requires.
Returns String?
pub fn Context::body_json(Self) -> Json?
Parse the request body as JSON, returning None for an empty body or one that does not parse — the total counterpart of reading a JSON body.
test {
let request : @moonasgi.Request = {
http_method: "POST",
path: "/login",
query_string: b"",
headers: [],
body: b"{\"user\":\"ada\"}",
}
assert_eq(@ctx.Context::new(request).body_json(), Some({ "user": "ada" }))
assert_eq(
@ctx.Context::new({ ..request, body: b"not json", }).body_json(),
None,
)
}Returns Json?
pub fn Context::cookie(Self, String) -> String?
Look up a cookie by name from the request Cookie header, which is a ; -separated list of key=value pairs. Spaces around a name or a value are the separators'; None if there is no Cookie header or the name is absent.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns String?
pub fn Context::digest_credentials(Self) -> String?
The credential of an Authorization: Digest <parameters> header — the comma-separated parameter list, verbatim . None when the header is absent or names another scheme; the scheme name is matched case-insensitively, as RFC 7235 requires.
Returns String?
pub fn Context::form(Self, limits? : @moonmime.Limits) -> @moonmime.Form?
The posted form — Form(...) and File(...) parameters.
Reading the body is moonhttp/form's job; what belongs here is knowing that a request has a Content-Type and handing it over. None means the form broke its bounds and was refused whole: a handler given the first thousand parts of a larger form would be answering a request nobody sent. An empty form is the other answer, and means the request carried none.
| Parameter | Type | Default |
|---|---|---|
| limits | @moonmime.Limits | optional |
Returns @moonmime.Form?
pub fn Context::http_basic(Self) -> HttpBasicCredentials?
The HTTP Basic credentials on this request , or None.
Returns HttpBasicCredentials?
pub fn Context::json_field(Self, String) -> Json?
Pull a single field out of a JSON object body by name, None if the body is absent, not an object, or lacks the field.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns Json?
pub fn Context::last_event_id(Self) -> String?
The id of the last event the client received, from the Last-Event-ID header an event source sends when it reconnects, so a stream can resume after it. None on a first connection; an empty value is one too, since a client with no id sends no header.
Returns String?
pub fn Context::new(@http.Request, params? : Map[String, String], scope? : @spec.HttpScope, background? : BackgroundTasks) -> Self
A context for request. The scope defaults to the one a server would build for the request alone, which is what a test or a hand-built context needs.
| Parameter | Type | Default |
|---|---|---|
| type only | @http.Request | required |
| params | Map[String, String] | optional |
| scope | @spec.HttpScope | optional |
| background | BackgroundTasks | optional |
Returns Self
pub fn Context::oauth2_password_form(Self) -> OAuth2PasswordRequestForm?
Read an OAuth2PasswordRequestForm off the request's urlencoded (or multipart) body. None when neither username nor password is present — the body isn't a password-grant form at all — and equally when the body is too large to be one, since a grant carries six fields and nothing that big is a login.
Returns OAuth2PasswordRequestForm?
pub fn Context::param(Self, String) -> String?
Look up a path parameter by name.
test {
let request : @moonasgi.Request = {
http_method: "GET",
path: "/users/42",
query_string: b"",
headers: [],
body: b"",
}
let ctx = @ctx.Context::new(request, params=Map([("id", "42")]))
assert_eq(ctx.param("id"), Some("42"))
assert_eq(ctx.param("name"), None)
}| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns String?
pub fn Context::query(Self, String, limits? : @moonurl.Limits) -> String?
Look up a query-string parameter by name, e.g. ?limit=10&q=cat%20dog. Keys and values are percent/plus-decoded, so q above reads back as cat dog. When a key repeats, the first occurrence wins; use query_all to read every one.
test {
let request : @moonasgi.Request = {
http_method: "GET",
path: "/search",
query_string: b"q=cat%20dog&q=fish",
headers: [],
body: b"",
}
let ctx = @ctx.Context::new(request)
assert_eq(ctx.query("q"), Some("cat dog"))
assert_eq(ctx.query_all("q"), ["cat dog", "fish"])
}| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| limits | @moonurl.Limits | optional |
Returns String?
pub fn Context::query_all(Self, String, limits? : @moonurl.Limits) -> Array[String]
Every value given for name, in the order they appear — ?tag=a&tag=b reads back as ["a", "b"]. Empty when the key is absent.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| limits | @moonurl.Limits | optional |
Returns Array[String]
pub fn Context::serve(Self, Bytes, filename? : String, media_type? : String, inline? : Bool, etag? : @conditional.Tag, modified? : @moondate.Moment, ranges? : Bool) -> @http.Response
[file_response] with the request weighed first (RFC 9110 §13, §14):
* 304 — the client's copy is current. * 412 — a precondition it stated does not hold. * 206 — it asked for part, one Content-Range or a multipart/byteranges. * 416 — it asked for what is not there.
Everything turns on etag. Left out, one is hashed from the content, which costs a pass over the body; pass @conditional.stamp(length~, modified~) for one stat's worth instead, or any tag of your own.
ranges=false withdraws the offer in Accept-Ranges.
| Parameter | Type | Default |
|---|---|---|
| type only | Bytes | required |
| filename | String | optional |
| media_type | String | optional |
| inline | Bool | optional |
| etag | @conditional.Tag | optional |
| modified | @moondate.Moment | optional |
| ranges | Bool | optional |
Returns @http.Response
pub fn Context::state(Self) -> Map[String, Json]
The lifespan state: a shallow copy of what the startup hooks stored, so a handler reads the shared resources and anything it adds stays with this request.
Returns Map[String, Json]
Methods on OAuth2PasswordRequestForm
pub fn OAuth2PasswordRequestForm::equal(Self, Self) -> Bool
Returns Bool
pub fn OAuth2PasswordRequestForm::not_equal(Self, Self) -> Bool
Returns Bool
@di
Dependency-injection container, providers, and scopes resolved per request.
Types
pub struct Deps { open : () -> DepsScope }
A container with its dependency value type erased (Container::erase builds one), so a non-generic App can hold one. Resolving through it runs a provider's factory and records its teardown exactly as Scope::get does; what it cannot do is hand the value back — which is precisely what a route-level dependency does not need, since dependencies=[...] discards the values it builds and keeps only their effects.
| Field | Type |
|---|---|
| open | () -> DepsScope |
pub struct DepsScope { resolve : (String) -> Bool close : (Error?) -> Unit }
One request's resolution scope over an erased container: resolve a key (false when nothing provides it), then close, handing any failure to the teardowns.
| Field | Type |
|---|---|
| resolve | (String) -> Bool |
| close | (Error?) -> Unit |
pub struct Scope[V] { container : Container[V] cache : Map[String, V] building : Map[String, Bool] teardowns : Array[(Error?) -> Unit] }
A request-scoped resolution scope. Each dependency is built at most once and its value cached for the life of the scope ( per-request dependency cache), and each built value's teardown is recorded to run — in reverse registration order (LIFO) — when the scope closes. Open one per request, resolve dependencies through it, then close it (or use Container::run).
| Field | Type |
|---|---|
| container | Container[V] |
| cache | Map[String, V] |
| building | Map[String, Bool] |
| teardowns | Array[(Error?) -> Unit] |
@endpoint
Typed request parameters and response specifications that describe and validate a route.
Functions
pub fn loc_str(ParamLoc) -> String
The OpenAPI in string for a location.
| Parameter | Type | Default |
|---|---|---|
| type only | ParamLoc | required |
Returns String
Methods on Endpoint
pub fn Endpoint::equal(Self, Self) -> Bool
Returns Bool
pub fn Endpoint::new(params? : Array[Param], request_body? : @schema.Schema, request_required? : Bool, request_examples? : Map[String, Example], responses? : Array[ResponseSpec]) -> Self
Build an endpoint descriptor. Everything is optional: a bare Endpoint::new() describes an endpoint with no parameters, no body, and (on emit) a default 200 OK response.
| Parameter | Type | Default |
|---|---|---|
| params | Array[Param] | optional |
| request_body | @schema.Schema | optional |
| request_required | Bool | optional |
| request_examples | Map[String, Example] | optional |
| responses | Array[ResponseSpec] | optional |
Returns Self
pub fn Endpoint::not_equal(Self, Self) -> Bool
Returns Bool
pub fn Endpoint::validate(Self, @ctx.Context) -> Array[@schema.ValidationError]
Validate an inbound request ctx against this endpoint descriptor: every declared parameter (path / query / header / cookie) plus the JSON request body, all off the same descriptor tree that emits the OpenAPI operation. Returns the accumulated errors — an empty array means the request conforms, otherwise pass them to unprocessable for a -shaped 422.
| Parameter | Type | Default |
|---|---|---|
| type only | @ctx.Context | required |
Returns Array[@schema.ValidationError]
Methods on Example
pub fn Example::equal(Self, Self) -> Bool
Returns Bool
pub fn Example::new(value? : Json, summary? : String, description? : String, external_value? : String) -> Self
| Parameter | Type | Default |
|---|---|---|
| value | Json | optional |
| summary | String | optional |
| description | String | optional |
| external_value | String | optional |
Returns Self
pub fn Example::not_equal(Self, Self) -> Bool
Returns Bool
pub fn Example::to_json(Self) -> Json
The Example Object for example. value and externalValue exclude each other, so a value given in both forms is written as the value.
Returns Json
Methods on Param
pub fn Param::equal(Self, Self) -> Bool
Returns Bool
pub fn Param::is_required(Self) -> Bool
Whether a request must carry this parameter. One with a default never must — its absence is answered by the default, exactly as a Python default argument is.
Returns Bool
pub fn Param::key(Self) -> String
The name this parameter travels under: its alias when it has one, else its own name. This is what is read off the request, what the document calls it, and what a validation error's loc points at — all three being the client's view of the parameter.
Returns String
pub fn Param::new(String, ParamLoc, schema? : @schema.Schema, required? : Bool, description? : String, constraints? : Array[@schema.Constraint], default? : Json, alias_? : String, examples? : Map[String, Example]) -> Self
Build a parameter descriptor. schema defaults to a string and required to true. constraints are the Pydantic-style bounds reads off a Query(ge=…, max_length=…) — emitted into the parameter's documented schema *and* enforced on the inbound value. default is emitted and makes the parameter optional, since a value that has one is never missing. alias is the name the parameter travels under when that differs from the one the code calls it . examples are offered by name in the documentation .
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | ParamLoc | required |
| schema | @schema.Schema | optional |
| required | Bool | optional |
| description | String | optional |
| constraints | Array[@schema.Constraint] | optional |
| default | Json | optional |
| alias_ | String | optional |
| examples | Map[String, Example] | optional |
Returns Self
pub fn Param::not_equal(Self, Self) -> Bool
Returns Bool
Methods on ParamLoc
pub fn ParamLoc::equal(Self, Self) -> Bool
Returns Bool
pub fn ParamLoc::not_equal(Self, Self) -> Bool
Returns Bool
Methods on ResponseSpec
pub fn ResponseSpec::equal(Self, Self) -> Bool
Returns Bool
pub fn ResponseSpec::new(Int32, description? : String, body? : @schema.Schema, examples? : Map[String, Example]) -> Self
Build a response descriptor. description defaults to "OK" and there is no body unless one is given.
| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| description | String | optional |
| body | @schema.Schema | optional |
| examples | Map[String, Example] | optional |
Returns Self
pub fn ResponseSpec::not_equal(Self, Self) -> Bool
Returns Bool
@exceptions
HTTP exceptions and the error types the framework raises and renders.
Types
pub type ExceptionHandler = (@ctx.Context, Error) -> @http.Response?
An exception handler: given the request context and the raised error, return Some(response) to handle it or None to defer to the next handler. The explicit MoonBit form of @app.exception_handler(ExcType) — the None case stands in for "this handler isn't registered for that type".
Functions
pub fn http_error(Int32, String, headers? : Array[(String, String)]) -> HttpException
Build an HttpException with a string detail — the common case — and optional extra headers. raise http_error(404, "Item not found") reads like raise HTTPException(404, "Item not found").
| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | String | required |
| headers | Array[(String, String)] | optional |
Returns HttpException
@openapi
The OpenAPI document model and the bundled documentation UIs.
Constants & values
pub let redoc_js : String
pub let scalar_js : String
pub let swagger_css : String
pub let swagger_js : String
The pages load their readers from a CDN at an exact version, so a page does not change under an application that did not change. Self-hosting is a matter of passing other URLs.
pub let swagger_redirect_js : String
Functions
pub fn redoc_ui(spec_url? : String, title? : String, js_url? : String, telemetry? : Bool) -> String
A ReDoc page rendering the document served at spec_url get_redoc_html): three panels, built for reading rather than for trying calls out. ReDoc reports usage to its maker unless told not to; telemetry is off unless turned on, since the page is served to this API's readers.
| Parameter | Type | Default |
|---|---|---|
| spec_url | String | optional |
| title | String | optional |
| js_url | String | optional |
| telemetry | Bool | optional |
Returns String
pub fn scalar_ui(spec_url? : String, title? : String, js_url? : String, extra? : Map[String, Json]) -> String
A Scalar API reference rendering the document served at spec_url: the reference and a request client on one page. extra is merged over the configuration passed to Scalar.createApiReference, which is where its theme, layout and authentication defaults go.
| Parameter | Type | Default |
|---|---|---|
| spec_url | String | optional |
| title | String | optional |
| js_url | String | optional |
| extra | Map[String, Json] | optional |
Returns String
pub fn swagger_redirect(js_url? : String) -> String
The page an OAuth2 authorisation started from Swagger UI returns to: it hands the code or token back to the window that opened it get_swagger_ui_oauth2_redirect_html).
| Parameter | Type | Default |
|---|---|---|
| js_url | String | optional |
Returns String
pub fn swagger_ui(spec_url? : String, title? : String, js_url? : String, css_url? : String, oauth2_redirect_url? : String, init_oauth? : Json, extra? : Map[String, Json]) -> String
A Swagger UI page rendering the document served at spec_url get_swagger_ui_html). oauth2_redirect_url is the page an OAuth2 flow returns to, served by swagger_redirect; init_oauth is handed to initOAuth to prefill the client id, scopes and the like; extra is merged over the settings passed to Swagger UI .
| Parameter | Type | Default |
|---|---|---|
| spec_url | String | optional |
| title | String | optional |
| js_url | String | optional |
| css_url | String | optional |
| oauth2_redirect_url | String | optional |
| init_oauth | Json | optional |
| extra | Map[String, Json] | optional |
Returns String
Methods on ApiInfo
pub fn ApiInfo::new() -> Self
The defaults an app starts with.
Returns Self
Methods on Contact
pub fn Contact::new(name? : String, url? : String, email? : String) -> Self
| Parameter | Type | Default |
|---|---|---|
| name | String | optional |
| url | String | optional |
String | optional |
Returns Self
Methods on ExternalDocs
pub fn ExternalDocs::new(String, description? : String) -> Self
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| description | String | optional |
Returns Self
pub fn ExternalDocs::to_json(Self) -> Json
The externalDocs object for docs, the same in every dialect.
Returns Json
Methods on License
pub fn License::new(String, url? : String, identifier? : String) -> Self
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| url | String | optional |
| identifier | String | optional |
Returns Self
Methods on Server
pub fn Server::new(String, description? : String) -> Self
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| description | String | optional |
Returns Self
Methods on Tag
pub fn Tag::new(String, description? : String, external_docs? : ExternalDocs) -> Self
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| description | String | optional |
| external_docs | ExternalDocs | optional |
Returns Self
pub fn Tag::to_json(Self) -> Json
The tag object, the same in every dialect.
Returns Json
Methods on Ui
pub fn Ui::equal(Self, Self) -> Bool
Returns Bool
pub fn Ui::not_equal(Self, Self) -> Bool
Returns Bool
pub fn Ui::to_repr(Self) -> @debug.Repr
Returns @debug.Repr
@route
Routers, route tables, class-based views, and mounting sub-applications.
Types
pub type ApiHandler = async (@ctx.Context) -> @http.Response
A route handler : the request context in, a response out. It runs async, so it can await a database or another service; a plain closure is one too, and a named function that is not async is registered as ctx => f(ctx). It may raise an HttpException (or any error) instead of returning — the app maps it to a response through the registered exception handlers.
pub type Hoop = async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply
A middleware on a route or on a router node : the request context and the rest of the route in, the reply out. It runs inside the app's own middleware and outside the route's security, validation and dependencies, so it can answer for the route — refuse, redirect, serve from a cache — or change what the route produced, and it can hand next a context of its own.
pub using @method {type Method}
The request method a route binds to: the nine standard ones and any other token, from moonhttp.
pub struct Router { routes : Array[Route] ws_routes : Array[WsRoute] hoops : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] }
A collection of routes built away from any application and folded into one with App::include_router . It carries the registration surface of an App and nothing else: middleware, mounts, security schemes, documentation and lifespan belong to the application that includes it.
| Field | Type |
|---|---|
| routes | Array[Route] |
| ws_routes | Array[WsRoute] |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] |
pub type StreamHandler = async (@ctx.Context) -> @status.Stream
A streaming route's handler : the response it returns writes its body while it is sent.
pub type Url = (Router) -> Unit
One entry of a route table: what it registers, given the router it lands on. path, view, websocket and group make them.
pub(open) trait View { fn get(Self) -> (async (@ctx.Context) -> @http.Response)? = _ fn head(Self) -> (async (@ctx.Context) -> @http.Response)? = _ fn post(Self) -> (async (@ctx.Context) -> @http.Response)? = _ fn put(Self) -> (async (@ctx.Context) -> @http.Response)? = _ fn patch(Self) -> (async (@ctx.Context) -> @http.Response)? = _ fn delete(Self) -> (async (@ctx.Context) -> @http.Response)? = _ fn options(Self) -> (async (@ctx.Context) -> @http.Response)? = _ fn trace(Self) -> (async (@ctx.Context) -> @http.Response)? = _ }
A type answering the methods of one path . Implement the methods it answers, each giving back its handler; the rest answer None, and a request for one of those gets a 405 whose Allow lists what the view does answer.
struct Articles { db : Db }
impl @moonapi.View for Articles with get(self) {
Some(ctx => self.db.list(ctx))
}
impl @moonapi.View for Articles with post(self) {
Some(ctx => self.db.create(ctx))
}
app.view("/articles", Articles::{ db })Functions
pub fn group(String, Array[(Router) -> Unit], tags? : Array[String], security? : Array[@security.SecurityRequirement], dependencies? : Array[String], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> (Router) -> Unit
urls under prefix reserved word). The arguments reach every route of the group as Router::include_router describes, and a group may hold groups.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | Array[(Router) -> Unit] | required |
| tags | Array[String] | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns (Router) -> Unit
pub fn join_prefix(String, String) -> String
A route path under prefix, written as writes it: the prefix with its trailing slashes dropped, then the path as given, so ("/sub", "/items/") is /sub/items/ and ("/sub", "/") is /sub/. A path keeps its own trailing slash because a trailing slash is part of what a route matches.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | String | required |
Returns String
pub fn path(String, async (@ctx.Context) -> @http.Response, methods? : Array[@method.Method], name? : String) -> (Router) -> Unit
handler at path for each of methods default is the same GET, which answers HEAD too).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| methods | Array[@method.Method] | optional |
| name | String | optional |
Returns (Router) -> Unit
pub fn segments(String) -> Array[String]
Split a path into its non-empty segments.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns Array[String]
pub fn view(String, &View, name? : String) -> (Router) -> Unit
The methods view answers at path.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | &View | required |
| name | String | optional |
Returns (Router) -> Unit
pub fn websocket(String, async (@socket.WebSocket) -> Unit, name? : String) -> (Router) -> Unit
A WebSocket route at path .
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@socket.WebSocket) -> Unit | required |
| name | String | optional |
Returns (Router) -> Unit
Methods on Convertor
pub fn Convertor::equal(Self, Self) -> Bool
Returns Bool
pub fn Convertor::not_equal(Self, Self) -> Bool
Returns Bool
pub fn Convertor::of(StringView) -> Self?
The convertor named name, as a template spells it after the colon.
| Parameter | Type | Default |
|---|---|---|
| type only | StringView | required |
Returns Self?
pub fn Convertor::to_repr(Self) -> @debug.Repr
Returns @debug.Repr
Methods on Pattern
pub fn Pattern::bind(Self, StringView) -> Map[String, String]?
The parameters path binds, or None when it does not match. The whole path must match: a trailing slash is a different path.
| Parameter | Type | Default |
|---|---|---|
| type only | StringView | required |
Returns Map[String, String]?
pub fn Pattern::equal(Self, Self) -> Bool
Returns Bool
pub fn Pattern::fill(Self, Map[String, String]) -> String?
The path with params substituted ; None when one is missing or does not fit its convertor.
| Parameter | Type | Default |
|---|---|---|
| type only | Map[String, String] | required |
Returns String?
pub fn Pattern::not_equal(Self, Self) -> Bool
Returns Bool
pub fn Pattern::params(Self) -> Array[(String, Convertor)]
The parameters in the order the path names them.
Returns Array[(String, Convertor)]
pub fn Pattern::parse(String) -> Self
Read path as a template. An unclosed brace, an empty name, an unknown convertor or two parameters with nothing between them is a mistake in the program, not in a request, so it aborts at registration — the way refuses such a route when the application starts.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns Self
pub fn Pattern::template(Self) -> String
The path as an OpenAPI template expression: every parameter as {name}, the convertor left to the parameter's schema.
Returns String
pub fn Pattern::to_repr(Self) -> @debug.Repr
Returns @debug.Repr
Methods on Piece
pub fn Piece::equal(Self, Self) -> Bool
Returns Bool
pub fn Piece::not_equal(Self, Self) -> Bool
Returns Bool
pub fn Piece::to_repr(Self) -> @debug.Repr
Returns @debug.Repr
Methods on Router
pub fn Router::delete(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register a DELETE route. A shorthand for route(Delete, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::get(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register a GET route. A shorthand for route(Get, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::head(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register a HEAD route. A shorthand for route(Head, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::hoop(Self, async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply) -> Unit
Put hoop around every route of this router . The router's hoops reach its routes when it is included, outside each route's own, in the order they were added.
| Parameter | Type | Default |
|---|---|---|
| type only | async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply | required |
Returns Unit
pub fn Router::include_router(Self, Self, prefix? : String, tags? : Array[String], security? : Array[@security.SecurityRequirement], dependencies? : Array[String], responses? : Array[@endpoint.ResponseSpec], deprecated? : Bool, include_in_schema? : Bool, hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Fold router's routes into this one under prefix APIRouter.include_router), so routers nest into a tree and the tree is included into an app once. The arguments reach every route folded in:
- tags, security, dependencies and hoops are placed before the route's own, so a group's tag leads and a group-wide requirement, dependency or hoop cannot be dropped by a route that adds one of its own; router's own hoops come between the two; - responses are documented under the route's, which therefore wins any status both name; - deprecated marks the whole group, and include_in_schema=false hides it, neither of which a route can undo.
WebSocket routes take the prefix, the security and the dependencies.
| Parameter | Type | Default |
|---|---|---|
| prefix | String | optional |
| tags | Array[String] | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| deprecated | Bool | optional |
| include_in_schema | Bool | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::new() -> Self
An empty router. The prefix and the attributes its routes share are given at include_router rather than here, so one router can be included twice — under a second prefix, or on another app with different tags.
Returns Self
pub fn Router::options(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register a OPTIONS route. A shorthand for route(Options, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::patch(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register a PATCH route. A shorthand for route(Patch, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::post(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register a POST route. A shorthand for route(Post, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::put(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register a PUT route. A shorthand for route(Put, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::route(Self, @method.Method, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register a route on the router for an explicit method. An optional endpoint descriptor makes the route fully typed (its parameters, request body, and responses surface in the OpenAPI document and drive validation); security attaches per-operation requirements (emitted as OpenAPI security and enforced before the handler when their scheme has an enforcer); dependencies names provider keys resolved through the app's container (App::depends) before the handler and torn down after it, whatever the handler did.
The rest describe the operation: summary and description are its prose, operation_id the stable handle client generators name their method after, status_code the status its success response is documented under, responses further documented responses, name the handle App::url_for resolves, openapi_extra a fragment merged over the generated operation object, and callbacks the requests this operation makes back to its caller, written as routes whose paths are runtime expressions — the same keyword arguments path operations take. hoops wrap this one route, inside any its routers put around it.
| Parameter | Type | Default |
|---|---|---|
| type only | @method.Method | required |
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::route_stream(Self, @method.Method, String, async (@ctx.Context) -> @status.Stream, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register a streaming route StreamingResponse). The handler's chunks reach the client as separate body events, so a long or open-ended reply starts arriving before it is finished.
A stream is only streamed as far as the app can honestly keep it one: a middleware that rewrites the body — gzip does — collapses the reply to a single chunk. Everything else about the route is ordinary; it documents, validates and enforces security exactly as route does.
| Parameter | Type | Default |
|---|---|---|
| type only | @method.Method | required |
| type only | String | required |
| type only | async (@ctx.Context) -> @status.Stream | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::stream(Self, String, async (@ctx.Context) -> @status.Stream, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register a streaming GET route — the verb a stream is nearly always read over, and what an SSE endpoint is. A shorthand for route_stream(Get, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @status.Stream | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::trace(Self, String, async (@ctx.Context) -> @http.Response, summary? : String, description? : String, tags? : Array[String], deprecated? : Bool, operation_id? : String, status_code? : Int32, responses? : Array[@endpoint.ResponseSpec], name? : String, endpoint? : @endpoint.Endpoint, security? : Array[@security.SecurityRequirement], dependencies? : Array[String], include_in_schema? : Bool, validate? : Bool, openapi_extra? : Json, callbacks? : Array[Route], hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register a TRACE route. A shorthand for route(Trace, ...).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@ctx.Context) -> @http.Response | required |
| summary | String | optional |
| description | String | optional |
| tags | Array[String] | optional |
| deprecated | Bool | optional |
| operation_id | String | optional |
| status_code | Int32 | optional |
| responses | Array[@endpoint.ResponseSpec] | optional |
| name | String | optional |
| endpoint | @endpoint.Endpoint | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| include_in_schema | Bool | optional |
| validate | Bool | optional |
| openapi_extra | Json | optional |
| callbacks | Array[Route] | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::urls(Self, Array[(Self) -> Unit]) -> Unit
Register every entry of urls, in order — the order a request tries them in.
| Parameter | Type | Default |
|---|---|---|
| type only | Array[(Self) -> Unit] | required |
Returns Unit
pub fn Router::view(Self, String, &View, name? : String, tags? : Array[String], security? : Array[@security.SecurityRequirement], dependencies? : Array[String], deprecated? : Bool, include_in_schema? : Bool, hoops? : Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply]) -> Unit
Register the methods view answers at path, each as its own route sharing the arguments given here. A view that answers no method is a mistake in the program and aborts.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | &View | required |
| name | String | optional |
| tags | Array[String] | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
| deprecated | Bool | optional |
| include_in_schema | Bool | optional |
| hoops | Array[async (@ctx.Context, async (@ctx.Context) -> Reply) -> Reply] | optional |
Returns Unit
pub fn Router::websocket(Self, String, async (@socket.WebSocket) -> Unit, name? : String, security? : Array[@security.SecurityRequirement], dependencies? : Array[String]) -> Unit
Register a WebSocket route on the router . It takes the including prefix like any other route. security and dependencies are checked before the handler runs, as on an HTTP route, and a refusal declines the handshake; name is the handle App::url_for resolves. The OpenAPI attributes do not apply, since a WebSocket route is not an operation.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | async (@socket.WebSocket) -> Unit | required |
| name | String | optional |
| security | Array[@security.SecurityRequirement] | optional |
| dependencies | Array[String] | optional |
Returns Unit
@schema
JSON Schema types, constraints, and validation used for bodies and documents.
Types
pub(open) trait ToSchema { fn to_schema(Self) -> Schema }
The impl-able version of a type's descriptor. A user struct implements it — the value is ignored; it exists so descriptor-carrying code can be generic over "a type that knows its own schema". The primary, mctl-friendly shape is still a plain associated function T::schema() -> Schema (no instance needed, mirroring referencing the model *class*); this trait bridges to it.
Constants & values
pub let query_limits : @moonurl.Limits
How much of a query string is a query string.
A thousand parameters is what qs allows by default, and far past anything a link carries; sixty-four kilobytes for one value is well past the eight the common servers allow a whole request line. Beyond either, the request is an attempt to make the server allocate.
An endpoint that genuinely takes more says so: ctx.query("tag", limits=@moonurl.Limits::new(pairs=100000)).
Functions
pub fn check_constraints(Json, Array[Constraint], Array[String], Array[ValidationError]) -> Unit
Enforce the constraints on an inbound value, appending a Pydantic-shaped ValidationError (located at loc) for each violation. A constraint that does not apply to the value's kind (a length bound on a number, say) is simply skipped, as pydantic does.
| Parameter | Type | Default |
|---|---|---|
| type only | Json | required |
| type only | Array[Constraint] | required |
| type only | Array[String] | required |
| type only | Array[ValidationError] | required |
Returns Unit
pub fn emit_schema(Schema, Map[String, Json], OpenApiVersion) -> Json
Emit schema as inline OpenAPI JSON, hoisting every *named* object into defs (keyed by name) and referencing it by $ref. Recursion-safe: a name is reserved in defs before its body is built, so a self-referential schema terminates instead of looping.
| Parameter | Type | Default |
|---|---|---|
| type only | Schema | required |
| type only | Map[String, Json] | required |
| type only | OpenApiVersion | required |
Returns Json
pub fn enum_expected(Array[Json]) -> String
The Pydantic-style "expected one of" fragment for an enum error: string members quoted, comma-separated, with a final or before the last.
| Parameter | Type | Default |
|---|---|---|
| type only | Array[Json] | required |
Returns String
pub fn enum_member(Array[Json], Json) -> Bool
Whether v is one of the allowed enum values.
| Parameter | Type | Default |
|---|---|---|
| type only | Array[Json] | required |
| type only | Json | required |
Returns Bool
pub fn filter_response(Schema, Json) -> Result[Json, Array[ValidationError]]
Validate value against model and, if it conforms, return it filtered down to the model's declared fields (extras dropped, nested objects and arrays projected too). On a mismatch return the located ValidationErrors under ["response"] — the same shape request validation produces. This is response_model: the outgoing shape is the model, not whatever the handler happened to build.
| Parameter | Type | Default |
|---|---|---|
| type only | Schema | required |
| type only | Json | required |
Returns Result[Json, Array[ValidationError]]
pub fn json_model(Int32, Schema, Json) -> @http.Response
A JSON response whose body is value filtered through model. On success a status response carrying only the model's declared fields; on a model mismatch a 500 whose body lists the response-validation errors — the return value didn't match what the route promised, which is a server-side fault.
| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | Schema | required |
| type only | Json | required |
Returns @http.Response
pub fn parse_int(String) -> Int32?
Parse a base-10 integer, None if s is not a well-formed integer literal (optional leading +/-, then one or more ASCII digits, nothing else).
Not core's @strconv.parse_int: that one also takes 0x prefixes and underscores, which a query or path parameter must not quietly accept.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns Int32?
pub fn unprocessable(Array[ValidationError]) -> @http.Response
A 422 Unprocessable Entity response whose application/json body lists the validation errors, exactly as reports a failed request.
| Parameter | Type | Default |
|---|---|---|
| type only | Array[ValidationError] | required |
Returns @http.Response
pub fn validate_schema(Schema, Json, Array[String], Array[ValidationError]) -> Unit
Validate a JSON value against the descriptor schema, appending -shaped errors to errs (located at loc). This is what "the descriptor drives validation" means: the very tree that emits the OpenAPI body schema also decides whether an inbound body conforms — one source of truth, exactly as pydantic derives both from one model. A named object is validated against its inline fields, so no $ref resolution is needed here.
| Parameter | Type | Default |
|---|---|---|
| type only | Schema | required |
| type only | Json | required |
| type only | Array[String] | required |
| type only | Array[ValidationError] | required |
Returns Unit
pub fn validation_error_body(Array[ValidationError]) -> Json
The {"detail": [ ... ]} body returns when request validation fails, built from a list of ValidationErrors.
| Parameter | Type | Default |
|---|---|---|
| type only | Array[ValidationError] | required |
Returns Json
pub fn with_constraints(Json, Array[Constraint], OpenApiVersion) -> Json
Merge the constraints into a scalar/array schema object for OpenAPI emission. exclusiveMinimum / exclusiveMaximum are numeric under OpenAPI 3.1 (JSON-Schema 2020-12) but a boolean flag alongside minimum / maximum under Swagger 2.0 and OpenAPI 3.0, so the form is version-aware.
| Parameter | Type | Default |
|---|---|---|
| type only | Json | required |
| type only | Array[Constraint] | required |
| type only | OpenApiVersion | required |
Returns Json
pub fn with_description(Json, String) -> Json
Return j with a description sibling added (legal beside $ref in OpenAPI 3.1 / JSON-Schema 2020-12).
| Parameter | Type | Default |
|---|---|---|
| type only | Json | required |
| type only | String | required |
Returns Json
pub fn with_key(Json, String, Json) -> Json
Return j with key set to value. Builds a fresh object so nothing shared mutates; a non-object is returned untouched, since there is nothing to set on it.
| Parameter | Type | Default |
|---|---|---|
| type only | Json | required |
| type only | String | required |
| type only | Json | required |
Returns Json
Methods on Constraint
pub fn Constraint::equal(Self, Self) -> Bool
Returns Bool
pub fn Constraint::not_equal(Self, Self) -> Bool
Returns Bool
pub fn Constraint::to_repr(Self) -> @debug.Repr
Returns @debug.Repr
Methods on Field
pub fn Field::equal(Self, Self) -> Bool
Returns Bool
pub fn Field::is_required(Self) -> Bool
Whether a body must carry this field. A field with a default never must — its absence is answered by the default, exactly as a Python default argument is, so it is left out of the emitted required list and not reported missing.
Returns Bool
pub fn Field::new(String, Schema, required? : Bool, description? : String, constraints? : Array[Constraint], default? : Json, examples? : Array[Json]) -> Self
Build a field. required defaults to true ( treats a field without a default as required). constraints are the Pydantic-style value constraints (ge/le/min_length/pattern/…) that are both emitted into the field's OpenAPI schema and enforced when validating an inbound value. default is emitted into the schema and makes the field optional, since a value that has one is never missing.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | Schema | required |
| required | Bool | optional |
| description | String | optional |
| constraints | Array[Constraint] | optional |
| default | Json | optional |
| examples | Array[Json] | optional |
Returns Self
pub fn Field::not_equal(Self, Self) -> Bool
Returns Bool
pub fn Field::to_repr(Self) -> @debug.Repr
Returns @debug.Repr
Methods on ObjectSchema
pub fn ObjectSchema::equal(Self, Self) -> Bool
Returns Bool
pub fn ObjectSchema::not_equal(Self, Self) -> Bool
Returns Bool
pub fn ObjectSchema::to_repr(Self) -> @debug.Repr
Returns @debug.Repr
Methods on OpenApiVersion
pub fn OpenApiVersion::equal(Self, Self) -> Bool
Returns Bool
pub fn OpenApiVersion::not_equal(Self, Self) -> Bool
Returns Bool
Methods on Schema
pub fn Schema::array(Self) -> Self
An array schema whose elements all conform to item.
Returns Self
pub fn Schema::binary() -> Self
The schema of file content: a string with OpenAPI's binary format — what an upload is described as, and what a multipart file field carries.
Returns Self
pub fn Schema::equal(Self, Self) -> Bool
Returns Bool
pub fn Schema::format(Self, String) -> Self
base refined by an OpenAPI format. The format is documentation: it tells a reader and a client generator what the string holds, and validation still checks only base, which is what pydantic does for a format it has no validator for.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns Self
pub fn Schema::json(Json) -> Self
A schema written as JSON Schema itself (2020-12, which is what OpenAPI 3.1 is). Use it for what the other constructors cannot say; it goes into the document unchanged.
| Parameter | Type | Default |
|---|---|---|
| type only | Json | required |
Returns Self
pub fn Schema::map(Self) -> Self
An object with no declared fields whose values all conform to value . Schema::map(SAny) is the free-form object.
Returns Self
pub fn Schema::not_equal(Self, Self) -> Bool
Returns Bool
pub fn Schema::nullable(Self) -> Self
A schema that also admits null . Wrapping rather than a flag because the three dialects express it three different ways.
Returns Self
pub fn Schema::object(String, Array[Field]) -> Self
A named object schema: hoisted to components/schemas under name and referenced by $ref wherever it is used.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | Array[Field] | required |
Returns Self
pub fn Schema::of_model(@moonmodel.Model, known? : Array[@moonmodel.Model]) -> (Self, Array[Unresolved])
A moonmodel description as a schema.
One description, written once, drives request validation and the OpenAPI document here, and the DDL and the SDL in their own libraries. known is where a Ref is looked up: a reference to a model that is not in it, or one that leads back to a model already being written, is reported instead — a schema is a finite value, so a cycle cannot be written out, and the name alone does not say what the thing looks like.
| Parameter | Type | Default |
|---|---|---|
| type only | @moonmodel.Model | required |
| known | Array[@moonmodel.Model] | optional |
Returns (Self, Array[Unresolved])
pub fn Schema::to_repr(Self) -> @debug.Repr
Returns @debug.Repr
Methods on Unresolved
pub fn Unresolved::equal(Self, Self) -> Bool
Returns Bool
pub fn Unresolved::not_equal(Self, Self) -> Bool
Returns Bool
Methods on ValidationError
pub fn ValidationError::missing(Array[String]) -> Self
The canonical "a required parameter was not supplied" error located at loc, matching {"type": "missing", "msg": "Field required"}.
| Parameter | Type | Default |
|---|---|---|
| type only | Array[String] | required |
Returns Self
pub fn ValidationError::to_json(Self) -> Json
Render one validation error as its JSON object.
Returns Json
pub fn ValidationError::type_error(Array[String], String, String) -> Self
A type/parse error located at loc, e.g. kind = "int_parsing" with the matching pydantic message — the shape reports for a value of the wrong type.
| Parameter | Type | Default |
|---|---|---|
| type only | Array[String] | required |
| type only | String | required |
| type only | String | required |
Returns Self
@security
Authentication schemes, security requirements, and their runtime enforcers.
Types
pub struct ApiKey { loc : ApiKeyIn name : String verify : (String) -> Bool }
An API-key scheme: the parameter name the key arrives under, where it arrives, and the predicate that accepts a presented key. APIKeyHeader only extracts and leaves the check to a dependency; a route guard needs both, so the check travels with the scheme.
| Field | Type |
|---|---|
| loc | ApiKeyIn |
| name | String |
| verify | (String) -> Bool |
pub struct BasicAuth { realm : String verify : (@ctx.HttpBasicCredentials) -> Bool }
An HTTP Basic scheme : the realm named in the challenge, and the predicate that accepts a presented username/password.
| Field | Type |
|---|---|
| realm | String |
| verify | (@ctx.HttpBasicCredentials) -> Bool |
pub struct DigestAuth { realm : String verify : (String) -> Bool }
An HTTP Digest scheme credential and no more): verify decides whether the Digest parameter string a client sent is acceptable. Computing the RFC 7616 response digest is the application's, since only it holds the password store.
| Field | Type |
|---|---|
| realm | String |
| verify | (String) -> Bool |
pub struct OAuth2CodeBearer { authorization_url : String token_url : String refresh_url : String secret : String }
An OAuth2 authorization-code bearer scheme OAuth2AuthorizationCodeBearer): the authorization_url a browser is sent to, the token_url the code is exchanged at, an optional refresh_url, and the shared HS256 secret a presented token is verified against.
| Field | Type |
|---|---|
| authorization_url | String |
| token_url | String |
| refresh_url | String |
| secret | String |
pub type SecurityEnforcer = (@ctx.Context, SecurityScopes, Int64) -> Result[AuthenticatedUser, @http.Response]
The runtime guard behind a named scheme: given the request context, the scopes the route required at this call site, and the verification time (Unix seconds), either the authenticated user or the 401/403 response to return. Registered by the App::secure_* functions; a documentation-only scheme (a bare add_security_scheme) has none, so it is described in the spec but not enforced — exactly split between a declared scheme and a wired dependency.
pub struct SecurityScopes { scopes : Array[String] }
The scopes a route required at the point its security guard runs SecurityScopes). A guard reads them to check what the caller was granted and to build the WWW-Authenticate challenge a 401 owes the client.
| Field | Type |
|---|---|
| scopes | Array[String] |
Functions
pub fn anonymous() -> AuthenticatedUser
The caller an auto_error=false guard admits: no subject, no scopes, no claims. auto_error=False hands the route None and lets it decide; the route here sees a caller it knows nothing about.
Returns AuthenticatedUser
pub fn create_access_token(String, String, Int64, scopes? : Array[String], expires_in_secs? : Int64, extra? : Map[String, Json], wins? : @jwt.Wins, clash? : @jwt.OnClash[Map[String, Json]]) -> String
Mint an HS256 access token for subject . Stamps sub, iat (= now_secs), exp (= now_secs + expires_in_secs), and, when non-empty, scopes; extra merges in any further claims. Times are Unix seconds. secret is the shared HS256 key.
extra adds claims. Where it names one the arguments already set — sub, iat, exp, scopes — the arguments win and saying it twice aborts, because a token whose subject is not the subject passed in is a mistake in the program rather than a choice about configuration. wins=Extra hands the decision to extra, and clash can silence it or take a callback.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | String | required |
| type only | Int64 | required |
| scopes | Array[String] | optional |
| expires_in_secs | Int64 | optional |
| extra | Map[String, Json] | optional |
| wins | @jwt.Wins | optional |
| clash | @jwt.OnClash[Map[String, Json]] | optional |
Returns String
pub fn forbidden(String) -> @http.Response
A 403 Forbidden with a {"detail": ...} body — returned when the token is valid but lacks a required scope. The token authenticated the caller, so this is authorization, not authentication: 403, not 401.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns @http.Response
pub fn hs256(String) -> @jwt.Keyed
The HS256 key a shared secret stands for.
This is the whole of moonapi's relationship with cryptography: it names an algorithm and hands mooncred something that can sign. Nothing here knows what SHA-256 is, and a deployment that wants ES256 passes its own signer to mooncred without moonapi being involved.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns @jwt.Keyed
pub fn refuse(Bool, () -> @http.Response) -> Result[AuthenticatedUser, @http.Response]
Admit an unauthenticated caller, or refuse with denied — the one place auto_error is decided, so every guard reads the flag the same way.
| Parameter | Type | Default |
|---|---|---|
| type only | Bool | required |
| type only | () -> @http.Response | required |
Returns Result[AuthenticatedUser, @http.Response]
pub fn token_response(String) -> @http.Response
The 200 token response body {"access_token": ..., "token_type": "bearer"} — the OAuth2 password-grant reply token endpoint returns.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns @http.Response
pub fn unauthorized(String, challenge? : String) -> @http.Response
A 401 Unauthorized with a WWW-Authenticate challenge and a {"detail": ...} body — response for a missing or invalid credential. RFC 9110 §15.5.2 requires the challenge, so it is a parameter: Basic realm="…" for Basic, Bearer scope="…" for a scoped bearer route.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| challenge | String | optional |
Returns @http.Response
pub fn verify_bearer(@ctx.Context, String, SecurityScopes, Int64, Bool) -> Result[AuthenticatedUser, @http.Response]
The guard every JWT-verified scheme shares — the OAuth2 password and authorization-code flows, a plain HTTP bearer, and OpenID Connect all present the same Authorization: Bearer <jwt> credential. Pulls the token, verifies it against secret at now, then checks the scopes the route required.
| Parameter | Type | Default |
|---|---|---|
| type only | @ctx.Context | required |
| type only | String | required |
| type only | SecurityScopes | required |
| type only | Int64 | required |
| type only | Bool | required |
Returns Result[AuthenticatedUser, @http.Response]
Methods on ApiKey
pub fn ApiKey::cookie(String, (String) -> Bool) -> Self
An API key read from the cookie name .
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | (String) -> Bool | required |
Returns Self
pub fn ApiKey::header(String, (String) -> Bool) -> Self
An API key read from the request header name .
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | (String) -> Bool | required |
Returns Self
pub fn ApiKey::query(String, (String) -> Bool) -> Self
An API key read from the query parameter name .
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | (String) -> Bool | required |
Returns Self
pub fn ApiKey::read(Self, @ctx.Context) -> String?
The key this request presents for the scheme, None when it carries none.
| Parameter | Type | Default |
|---|---|---|
| type only | @ctx.Context | required |
Returns String?
pub fn ApiKey::scheme(Self) -> SecurityScheme
The apiKey scheme object this key is documented as.
Returns SecurityScheme
Methods on ApiKeyIn
pub fn ApiKeyIn::equal(Self, Self) -> Bool
Returns Bool
pub fn ApiKeyIn::not_equal(Self, Self) -> Bool
Returns Bool
Methods on AuthenticatedUser
pub fn AuthenticatedUser::has_scope(Self, String) -> Bool
Whether this user was granted scope.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns Bool
Methods on BasicAuth
pub fn BasicAuth::challenge(Self) -> String
The WWW-Authenticate value this scheme challenges with.
Returns String
pub fn BasicAuth::new((@ctx.HttpBasicCredentials) -> Bool, realm? : String) -> Self
Build an HTTP Basic scheme. A realm is optional and, when given, names the protection space in the challenge so a browser can tell one login from another.
| Parameter | Type | Default |
|---|---|---|
| type only | (@ctx.HttpBasicCredentials) -> Bool | required |
| realm | String | optional |
Returns Self
Methods on DigestAuth
pub fn DigestAuth::challenge(Self) -> String
The WWW-Authenticate value this scheme challenges with.
Returns String
pub fn DigestAuth::new((String) -> Bool, realm? : String) -> Self
Build an HTTP Digest scheme, optionally naming the protection realm.
| Parameter | Type | Default |
|---|---|---|
| type only | (String) -> Bool | required |
| realm | String | optional |
Returns Self
Methods on OAuth2CodeBearer
pub fn OAuth2CodeBearer::new(String, String, String, refresh_url? : String) -> Self
Build an authorization-code bearer scheme. refresh_url is left out of the document when empty, since a provider that offers no refresh endpoint should not be described as having one.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | String | required |
| type only | String | required |
| refresh_url | String | optional |
Returns Self
pub fn OAuth2CodeBearer::scheme(Self, scopes? : Array[(String, String)]) -> SecurityScheme
The security scheme that describes this flow, advertising scopes.
| Parameter | Type | Default |
|---|---|---|
| scopes | Array[(String, String)] | optional |
Returns SecurityScheme
Methods on OAuth2PasswordBearer
pub fn OAuth2PasswordBearer::authenticate(Self, @ctx.Context, Int64, scopes? : Array[String]) -> Result[AuthenticatedUser, @http.Response]
Authenticate a request against this scheme and enforce scopes . On success returns the AuthenticatedUser; otherwise the response to return:
- no bearer token -> 401 {"detail":"Not authenticated"} - malformed / bad-signature / expired / not-yet-valid token -> 401 {"detail":"Could not validate credentials"} - valid token missing a required scope -> 403 {"detail":"Not enough permissions"}
Both 401s carry the challenge the required scopes describe — Bearer on its own, or Bearer scope="..." — so a client learns what it should have asked for.
now_secs is the verification time (Unix seconds), passed in so the check stays pure and testable on every backend.
| Parameter | Type | Default |
|---|---|---|
| type only | @ctx.Context | required |
| type only | Int64 | required |
| scopes | Array[String] | optional |
Returns Result[AuthenticatedUser, @http.Response]
pub fn OAuth2PasswordBearer::new(String, String) -> Self
Build a password-bearer scheme pointing at the token endpoint at token_url, verifying tokens with secret.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | String | required |
Returns Self
pub fn OAuth2PasswordBearer::scheme(Self, scopes? : Array[(String, String)]) -> SecurityScheme
Build the security scheme that describes this password-bearer flow object derives from OAuth2PasswordBearer). scopes are the (name, description) pairs advertised in the OpenAPI document.
| Parameter | Type | Default |
|---|---|---|
| scopes | Array[(String, String)] | optional |
Returns SecurityScheme
Methods on SecurityRequirement
pub fn SecurityRequirement::equal(Self, Self) -> Bool
Returns Bool
pub fn SecurityRequirement::new(String, scopes? : Array[String]) -> Self
Require scheme with the given scopes (default: none — authentication with no scope check). App::get(..., security=[SecurityRequirement::new("OAuth2", scopes=["items"])]) reads like Security(oauth2, scopes=["items"]).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| scopes | Array[String] | optional |
Returns Self
pub fn SecurityRequirement::not_equal(Self, Self) -> Bool
Returns Bool
pub fn SecurityRequirement::to_json(Self) -> Json
This requirement as its OpenAPI security entry: {scheme: [scope, ...]}.
Returns Json
Methods on SecurityScheme
pub fn SecurityScheme::to_openapi_20(Self) -> Json?
This scheme as a Swagger 2.0 security definition, or None when 2.0 cannot express it. Swagger 2.0 has no http type: an HTTP bearer or digest is expressed as an apiKey in the Authorization header (the standard 2.0 workaround), Basic uses the basic type, and OAuth2 flows are the flat 2.0 form (flow + URLs at top level, accessCode being 2.0's name for the authorization-code flow). Swagger 2.0 apiKey only allows header/query, so a cookie key maps to a header. OpenID Connect has no 2.0 equivalent at all, and inventing one would describe an API that does not exist — so it is left out of the 2.0 document.
Returns Json?
pub fn SecurityScheme::to_openapi_3x(Self) -> Json
This scheme as an OpenAPI 3.0 / 3.1 security scheme object.
Returns Json
Methods on SecurityScopes
pub fn SecurityScopes::challenge(Self) -> String
The WWW-Authenticate value a bearer challenge carries: Bearer on its own, or Bearer scope="a b" when the route requires scopes, which is how RFC 6750 §3 tells a client what it was missing.
Returns String
pub fn SecurityScopes::list(Self) -> Array[String]
The required scopes, in declaration order.
Returns Array[String]
pub fn SecurityScopes::new(scopes? : Array[String]) -> Self
The scopes required at one call site; empty means authentication only.
| Parameter | Type | Default |
|---|---|---|
| scopes | Array[String] | optional |
Returns Self
pub fn SecurityScopes::scope_str(Self) -> String
The scopes as OAuth2's single space-delimited string .
Returns String
@socket
WebSocket connections, messages, and lifecycle handling.
Types
pub struct WebSocket { scope : @spec.WebSocketScope params : Map[String, String] // private fields }
A WebSocket connection as a handler sees it.
| Field | Type |
|---|---|
| scope | @spec.WebSocketScope |
| params | Map[String, String] |
pub type WsHandler = async (WebSocket) -> Unit
A WebSocket route's handler .
Methods on Disconnected
pub fn Disconnected::equal(Self, Self) -> Bool
Returns Bool
pub fn Disconnected::not_equal(Self, Self) -> Bool
Returns Bool
pub fn Disconnected::to_repr(Self) -> @debug.Repr
Returns @debug.Repr
Methods on WebSocket
pub async fn WebSocket::accept(Self, subprotocol? : String, headers? : Array[(String, String)]) -> Unit
Take the connect, then accept with subprotocol and extra headers on the handshake.
| Parameter | Type | Default |
|---|---|---|
| subprotocol | String | optional |
| headers | Array[(String, String)] | optional |
Returns Unit
pub async fn WebSocket::close(Self, code? : Int32, reason? : String) -> Unit
Close with code and reason. Before accept this declines the handshake, which a server answers with 403.
| Parameter | Type | Default |
|---|---|---|
| code | Int32 | optional |
| reason | String | optional |
Returns Unit
pub async fn WebSocket::deny(Self, @http.Response) -> Unit
Decline the handshake with response : the client gets its status, headers and body instead of a WebSocket. That takes ASGI's websocket.http.response extension; a server without it is sent close code 1008 instead, which it answers with 403. After accept there is no handshake left to decline, and the connection is closed with 1008.
| Parameter | Type | Default |
|---|---|---|
| type only | @http.Response | required |
Returns Unit
pub fn WebSocket::header(Self, String) -> String?
The first request header named name (lowercase, as ASGI carries them).
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns String?
pub fn WebSocket::new(@spec.WebSocketScope, async () -> @spec.Event, async (@spec.Event) -> Unit, params? : Map[String, String]) -> Self
A WebSocket over an ASGI connection. The app makes one per connection; a driver of its own makes one over its receive and send.
| Parameter | Type | Default |
|---|---|---|
| type only | @spec.WebSocketScope | required |
| type only | async () -> @spec.Event | required |
| type only | async (@spec.Event) -> Unit | required |
| params | Map[String, String] | optional |
Returns Self
pub fn WebSocket::offered_subprotocols(Self) -> Array[String]
The subprotocols the client offered, in its order of preference.
Returns Array[String]
pub fn WebSocket::param(Self, String) -> String?
A path parameter by name.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns String?
pub async fn WebSocket::receive(Self) -> WsMessage
The next message. Raises Disconnected when the peer has left.
Returns WsMessage
pub async fn WebSocket::receive_bytes(Self) -> Bytes
The next message, which must be binary; a text message is taken as its UTF-8.
Returns Bytes
pub async fn WebSocket::receive_json(Self) -> Json
The next message parsed as JSON.
Returns Json
pub async fn WebSocket::receive_text(Self) -> String
The next message, which must be text; a binary message is taken as its UTF-8.
Returns String
pub async fn WebSocket::send(Self, WsMessage) -> Unit
Send message.
| Parameter | Type | Default |
|---|---|---|
| type only | WsMessage | required |
Returns Unit
pub async fn WebSocket::send_bytes(Self, Bytes) -> Unit
Send a binary message.
| Parameter | Type | Default |
|---|---|---|
| type only | Bytes | required |
Returns Unit
pub async fn WebSocket::send_json(Self, Json) -> Unit
Send value serialised as a text message.
| Parameter | Type | Default |
|---|---|---|
| type only | Json | required |
Returns Unit
pub async fn WebSocket::send_text(Self, String) -> Unit
Send a text message.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns Unit
Methods on WsMessage
pub fn WsMessage::equal(Self, Self) -> Bool
Returns Bool
pub fn WsMessage::not_equal(Self, Self) -> Bool
Returns Bool
pub fn WsMessage::to_repr(Self) -> @debug.Repr
Returns @debug.Repr
@static
Static file serving with content types and range support.
Types
pub struct Memory { files : Map[String, Asset] }
Files held in the program, keyed by their relative path: built into the binary, generated at startup, or read once from anywhere. Works on every target.
| Field | Type |
|---|---|
| files | Map[String, Asset] |
pub(open) trait Source { async fn read(Self, String) -> Asset? }
Where the served files come from. path is relative, its parts joined by /, and already checked: no empty part, no . or .., no backslash, colon or NUL. None means there is no such file.
Memory serves files held in the program and Directory (native) serves a directory; a source of your own — an archive, a bucket, a database — is one more implementation.
Functions
pub fn serve(&Source, html? : Bool, ranges? : Bool) -> async (@spec.Scope, async () -> @spec.Event, async (@spec.Event) -> Unit) -> Unit
Serve the files source holds, as an ASGI application to mount with App::mount_asgi .
A GET or HEAD for a file answers with it, weighed against the request's conditional headers and Range (304, 412, 206, 416), its type guessed from its name and its entity-tag taken from its date and length when the source knows the date. Any other method is a 405. A path with a .. part is a 404, never a file outside the source: clients resolve dot segments before sending, so only a crafted request carries one.
With html, a directory answers with its index.html, a directory named without its trailing slash is first sent to the name with one (307), and a path with nothing behind it answers with 404.html when there is one. ranges=false withdraws the offer of partial content.
| Parameter | Type | Default |
|---|---|---|
| type only | &Source | required |
| html | Bool | optional |
| ranges | Bool | optional |
Returns async (@spec.Scope, async () -> @spec.Event, async (@spec.Event) -> Unit) -> Unit
Methods on Asset
pub fn Asset::equal(Self, Self) -> Bool
Returns Bool
pub fn Asset::not_equal(Self, Self) -> Bool
Returns Bool
Methods on Memory
pub fn Memory::new(Map[String, Bytes], modified? : @moondate.Moment) -> Self
A memory source over files, every one dated modified when given.
| Parameter | Type | Default |
|---|---|---|
| type only | Map[String, Bytes] | required |
| modified | @moondate.Moment | optional |
Returns Self
pub async fn Memory::read(Self, String) -> Asset?
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns Asset?
@status
Response constructors, streaming, server-sent events, and background work.
Types
pub using @cookie {type Cookie}
pub using @sse {type Event}
pub struct Events { // private fields }
The event side of a text/event-stream: each send is one frame, written as its own chunk.
pub using @cookie {type SameSite}
pub struct Writer { // private fields }
Where a stream's body goes. The app makes one per response; a test or another driver makes one over its own sink.
Constants & values
pub const HTTP_100_CONTINUE : Int32 = 100
Continue: the headers are acceptable, send the body.
pub const HTTP_101_SWITCHING_PROTOCOLS : Int32 = 101
Switching Protocols: the server is changing to the protocol Upgrade asked for.
pub const HTTP_102_PROCESSING : Int32 = 102
Processing: WebDAV, the request is under way and the reply will follow.
pub const HTTP_103_EARLY_HINTS : Int32 = 103
Early Hints: preload links sent ahead of the real response.
pub const HTTP_200_OK : Int32 = 200
OK.
pub const HTTP_201_CREATED : Int32 = 201
Created: the request made a new resource, named in Location.
pub const HTTP_202_ACCEPTED : Int32 = 202
Accepted: taken for processing, outcome not yet known.
pub const HTTP_203_NON_AUTHORITATIVE_INFORMATION : Int32 = 203
Non-Authoritative Information: an intermediary altered the origin's payload.
pub const HTTP_204_NO_CONTENT : Int32 = 204
No Content: succeeded, and there is nothing to send back.
pub const HTTP_205_RESET_CONTENT : Int32 = 205
Reset Content: succeeded; the client should clear the form that sent it.
pub const HTTP_206_PARTIAL_CONTENT : Int32 = 206
Partial Content: the byte ranges Range asked for.
pub const HTTP_207_MULTI_STATUS : Int32 = 207
Multi-Status: WebDAV, one status per member of a collection.
pub const HTTP_208_ALREADY_REPORTED : Int32 = 208
Already Reported: WebDAV, this member was enumerated earlier in the reply.
pub const HTTP_226_IM_USED : Int32 = 226
IM Used: the body is the result of applying delta encodings.
pub const HTTP_300_MULTIPLE_CHOICES : Int32 = 300
Multiple Choices: several representations, pick one.
pub const HTTP_301_MOVED_PERMANENTLY : Int32 = 301
Moved Permanently: use Location from now on.
pub const HTTP_302_FOUND : Int32 = 302
Found: a temporary move. Clients rewrite POST to GET here, which is why 307 exists.
pub const HTTP_303_SEE_OTHER : Int32 = 303
See Other: fetch the outcome with a GET at Location — the redirect after a form post.
pub const HTTP_304_NOT_MODIFIED : Int32 = 304
Not Modified: the client's cached copy is still current.
pub const HTTP_305_USE_PROXY : Int32 = 305
Use Proxy: deprecated by RFC 9110.
pub const HTTP_306_RESERVED : Int32 = 306
Reserved: never standardised, and reserved so nothing else claims it.
pub const HTTP_307_TEMPORARY_REDIRECT : Int32 = 307
Temporary Redirect: like 302, but the method and body must be kept.
pub const HTTP_308_PERMANENT_REDIRECT : Int32 = 308
Permanent Redirect: like 301, but the method and body must be kept.
pub const HTTP_400_BAD_REQUEST : Int32 = 400
Bad Request: malformed enough that the server will not act on it.
pub const HTTP_401_UNAUTHORIZED : Int32 = 401
Unauthorized: not authenticated. The reply must carry WWW-Authenticate.
pub const HTTP_402_PAYMENT_REQUIRED : Int32 = 402
Payment Required: reserved.
pub const HTTP_403_FORBIDDEN : Int32 = 403
Forbidden: authenticated, and still not allowed.
pub const HTTP_404_NOT_FOUND : Int32 = 404
Not Found.
pub const HTTP_405_METHOD_NOT_ALLOWED : Int32 = 405
Method Not Allowed: the path exists under another verb, listed in Allow.
pub const HTTP_406_NOT_ACCEPTABLE : Int32 = 406
Not Acceptable: nothing on offer matches the request's Accept.
pub const HTTP_407_PROXY_AUTHENTICATION_REQUIRED : Int32 = 407
Proxy Authentication Required.
pub const HTTP_408_REQUEST_TIMEOUT : Int32 = 408
Request Timeout: the client took too long to send it.
pub const HTTP_409_CONFLICT : Int32 = 409
Conflict: it clashes with the resource's current state.
pub const HTTP_410_GONE : Int32 = 410
Gone: it existed and was removed on purpose.
pub const HTTP_411_LENGTH_REQUIRED : Int32 = 411
Length Required: Content-Length is missing and this server insists on it.
pub const HTTP_412_PRECONDITION_FAILED : Int32 = 412
Precondition Failed: an If-* header did not hold.
pub const HTTP_413_REQUEST_ENTITY_TOO_LARGE : Int32 = 413
Content Too Large — name keeps RFC 7231's "Request Entity Too Large".
pub const HTTP_414_REQUEST_URI_TOO_LONG : Int32 = 414
URI Too Long — name keeps RFC 7231's "Request-URI Too Long".
pub const HTTP_415_UNSUPPORTED_MEDIA_TYPE : Int32 = 415
Unsupported Media Type: the body's Content-Type is one this route cannot read.
pub const HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE : Int32 = 416
Range Not Satisfiable: no part of the requested range exists.
pub const HTTP_417_EXPECTATION_FAILED : Int32 = 417
Expectation Failed: the Expect header cannot be met.
pub const HTTP_418_IM_A_TEAPOT : Int32 = 418
I'm a Teapot: RFC 2324's joke, kept because clients test for it.
pub const HTTP_421_MISDIRECTED_REQUEST : Int32 = 421
Misdirected Request: this connection is not authoritative for that authority.
pub const HTTP_422_UNPROCESSABLE_ENTITY : Int32 = 422
Unprocessable Content: well-formed, and it fails validation — what unprocessable returns.
pub const HTTP_423_LOCKED : Int32 = 423
Locked: WebDAV, the resource is locked.
pub const HTTP_424_FAILED_DEPENDENCY : Int32 = 424
Failed Dependency: WebDAV, a request this one depended on failed.
pub const HTTP_425_TOO_EARLY : Int32 = 425
Too Early: replaying this early-data request could be a replay attack.
pub const HTTP_426_UPGRADE_REQUIRED : Int32 = 426
Upgrade Required: resend over the protocol named in Upgrade.
pub const HTTP_428_PRECONDITION_REQUIRED : Int32 = 428
Precondition Required: the server refuses to act on an unconditional write.
pub const HTTP_429_TOO_MANY_REQUESTS : Int32 = 429
Too Many Requests: rate limited; Retry-After says when to come back.
pub const HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE : Int32 = 431
Request Header Fields Too Large.
pub const HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS : Int32 = 451
Unavailable For Legal Reasons.
pub const HTTP_500_INTERNAL_SERVER_ERROR : Int32 = 500
Internal Server Error: the fallback for an error the app did not map.
pub const HTTP_501_NOT_IMPLEMENTED : Int32 = 501
Not Implemented: the server does not support the method at all.
pub const HTTP_502_BAD_GATEWAY : Int32 = 502
Bad Gateway: an upstream sent something invalid.
pub const HTTP_503_SERVICE_UNAVAILABLE : Int32 = 503
Service Unavailable: down or overloaded, and expected back.
pub const HTTP_504_GATEWAY_TIMEOUT : Int32 = 504
Gateway Timeout: an upstream did not answer in time.
pub const HTTP_505_HTTP_VERSION_NOT_SUPPORTED : Int32 = 505
HTTP Version Not Supported.
pub const HTTP_506_VARIANT_ALSO_NEGOTIATES : Int32 = 506
Variant Also Negotiates: the negotiation is configured in a circle.
pub const HTTP_507_INSUFFICIENT_STORAGE : Int32 = 507
Insufficient Storage: WebDAV, no room to store the representation.
pub const HTTP_508_LOOP_DETECTED : Int32 = 508
Loop Detected: WebDAV, the traversal is cyclic.
pub const HTTP_510_NOT_EXTENDED : Int32 = 510
Not Extended.
pub const HTTP_511_NETWORK_AUTHENTICATION_REQUIRED : Int32 = 511
Network Authentication Required: a captive portal wants a login first.
pub const WS_1000_NORMAL_CLOSURE : Int32 = 1000
Normal Closure: the purpose the connection was opened for is fulfilled.
pub const WS_1001_GOING_AWAY : Int32 = 1001
Going Away: the peer is shutting down or navigating off the page.
pub const WS_1002_PROTOCOL_ERROR : Int32 = 1002
Protocol Error.
pub const WS_1003_UNSUPPORTED_DATA : Int32 = 1003
Unsupported Data: a frame of a type this endpoint cannot accept.
pub const WS_1005_NO_STATUS_RCVD : Int32 = 1005
No Status Received: reported locally when a close frame carried no code.
pub const WS_1006_ABNORMAL_CLOSURE : Int32 = 1006
Abnormal Closure: reported locally when the connection died without a close frame.
pub const WS_1007_INVALID_FRAME_PAYLOAD_DATA : Int32 = 1007
Invalid Frame Payload Data: a text frame that is not valid UTF-8, say.
pub const WS_1008_POLICY_VIOLATION : Int32 = 1008
Policy Violation: the generic refusal when no other code fits.
pub const WS_1009_MESSAGE_TOO_BIG : Int32 = 1009
Message Too Big.
pub const WS_1010_MANDATORY_EXT : Int32 = 1010
Mandatory Extension: the client required an extension the server did not negotiate.
pub const WS_1011_INTERNAL_ERROR : Int32 = 1011
Internal Error: the server hit an unexpected condition.
pub const WS_1012_SERVICE_RESTART : Int32 = 1012
Service Restart.
pub const WS_1013_TRY_AGAIN_LATER : Int32 = 1013
Try Again Later: overloaded; come back.
pub const WS_1014_BAD_GATEWAY : Int32 = 1014
Bad Gateway: the gateway got an invalid response upstream.
pub const WS_1015_TLS_HANDSHAKE : Int32 = 1015
TLS Handshake: reported locally when the handshake failed.
Functions
pub fn data_response(String, filename? : String, status? : Int32, inline? : Bool) -> @http.Response?
Serve what a data: URL carries (RFC 2397), under the media type it names — what canvas.toDataURL() and FileReader.readAsDataURL() hand back.
None when it is not a data URL, so a handler tells "no picture" from "not a picture" without touching base64.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| filename | String | optional |
| status | Int32 | optional |
| inline | Bool | optional |
Returns @http.Response?
pub fn data_url(Bytes, media_type? : String) -> String
The content as a data: URL, for embedding it instead of costing a second request.
| Parameter | Type | Default |
|---|---|---|
| type only | Bytes | required |
| media_type | String | optional |
Returns String
pub fn delete_cookie(@http.Response, String, path? : String?, domain? : String, secure? : Bool, http_only? : Bool, same_site? : @cookie.SameSite?) -> @http.Response
Expire the cookie named name : an empty value with Max-Age=0 and a date in the past, so a browser that honours only one of the two still drops it.
A cookie is identified by name, domain and path together, so path and domain must match what set it — otherwise this writes a second, differently scoped cookie and the original survives.
| Parameter | Type | Default |
|---|---|---|
| type only | @http.Response | required |
| type only | String | required |
| path | String? | optional |
| domain | String | optional |
| secure | Bool | optional |
| http_only | Bool | optional |
| same_site | @cookie.SameSite? | optional |
Returns @http.Response
pub fn envelope(Int32, String, String, Bool) -> Array[(String, String)]
What the body is, how long, and what to save it as.
| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | String | required |
| type only | String | required |
| type only | Bool | required |
Returns Array[(String, String)]
pub fn file_response(Bytes, filename? : String, media_type? : String, status? : Int32, inline? : Bool) -> @http.Response
A download : a media type from filename's extension unless media_type names one, Content-Length, and a Content-Disposition. No filename, no disposition.
Bytes rather than a path: the same app runs on four backends and only the server can read a file on any of them.
Always the whole thing. [Context::serve] weighs the request first.
| Parameter | Type | Default |
|---|---|---|
| type only | Bytes | required |
| filename | String | optional |
| media_type | String | optional |
| status | Int32 | optional |
| inline | Bool | optional |
Returns @http.Response
pub fn html(Int32, String) -> @http.Response
An HTML response — what the documentation pages are served as.
test {
let page = @status.html(200, "<h1>Hello</h1>")
assert_eq(page.header("content-type"), Some("text/html; charset=utf-8"))
}| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | String | required |
Returns @http.Response
pub fn json(Int32, Json) -> @http.Response
A JSON response serialised from a Json value.
test {
let reply = @status.json(200, { "name": "Ada" })
assert_eq(reply.header("content-type"), Some("application/json"))
assert_eq(reply.body, b"{\"name\":\"Ada\"}")
}| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | Json | required |
Returns @http.Response
pub fn redirect(String, status? : Int32) -> @http.Response
A redirect to url .
307 keeps the method and body, which 302 historically does not. Use 303 after a write, 301 / 308 for a permanent move.
The URL is escaped as a whole URI reference, so an encoded one is not encoded twice and a \r\n cannot open a header of its own.
test {
let moved = @status.redirect("/new")
assert_eq(moved.status, 307)
assert_eq(moved.header("location"), Some("/new"))
}| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| status | Int32 | optional |
Returns @http.Response
pub fn set_cookie(@http.Response, String, String, max_age? : Int32, expires? : @moondate.Moment, path? : String?, domain? : String, secure? : Bool, http_only? : Bool, same_site? : @cookie.SameSite?) -> @http.Response
Add a Set-Cookie header to resp , returning the response that carries it; the original is untouched, so a handler can hand the same base response to two callers.
max_age is the lifetime in seconds and expires the moment it dies; giving neither makes it a session cookie. path defaults to /, and None omits the attribute so the cookie scopes to the request's own directory. http_only keeps it away from scripts, secure keeps it off plaintext connections, and same_site defaults to Lax — the browser default, and the one that stops a cross-site form post from carrying a session.
| Parameter | Type | Default |
|---|---|---|
| type only | @http.Response | required |
| type only | String | required |
| type only | String | required |
| max_age | Int32 | optional |
| expires | @moondate.Moment | optional |
| path | String? | optional |
| domain | String | optional |
| secure | Bool | optional |
| http_only | Bool | optional |
| same_site | @cookie.SameSite? | optional |
Returns @http.Response
pub fn sse(async (Events) -> Unit, status? : Int32, headers? : Array[(String, String)], space? : Bool, wins? : @jwt.Wins, clash? : @jwt.OnClash[Array[(String, String)]]) -> Stream
A text/event-stream response . body sends frames for as long as it likes; the app cancels it when the client goes.
Framing an event is moonhttp/sse's job. What belongs here is the response around the frames, and the three headers that stop an intermediary buffering or closing the stream. One named in headers too replaces ours rather than joining it, because a response carrying two content-type headers is not a response with a choice in it. wins=Base keeps ours, and clash can abort or take a callback instead — worth setting when overriding content-type, which stops the stream being a stream.
| Parameter | Type | Default |
|---|---|---|
| type only | async (Events) -> Unit | required |
| status | Int32 | optional |
| headers | Array[(String, String)] | optional |
| space | Bool | optional |
| wins | @jwt.Wins | optional |
| clash | @jwt.OnClash[Array[(String, String)]] | optional |
Returns Stream
pub fn text(Int32, String) -> @http.Response
A plain-text response.
test {
let reply = @status.text(200, "Hello")
assert_eq(reply.header("content-type"), Some("text/plain; charset=utf-8"))
assert_eq(reply.body, b"Hello")
}| Parameter | Type | Default |
|---|---|---|
| type only | Int32 | required |
| type only | String | required |
Returns @http.Response
Methods on Events
pub async fn Events::ping(Self, comment? : String) -> Unit
Send a comment line, which a client ignores and an idle proxy takes as traffic.
| Parameter | Type | Default |
|---|---|---|
| comment | String | optional |
Returns Unit
pub async fn Events::send(Self, @sse.Event) -> Unit
Send event as one frame. A client dispatches it when it reads the frame's blank line, so it goes out on its own rather than waiting for the next.
| Parameter | Type | Default |
|---|---|---|
| type only | @sse.Event | required |
Returns Unit
Methods on Stream
pub fn Stream::new(async (Writer) -> Unit, status? : Int32, headers? : Array[(String, String)], early_hints? : Array[Array[String]], trailers? : Bool) -> Self
| Parameter | Type | Default |
|---|---|---|
| type only | async (Writer) -> Unit | required |
| status | Int32 | optional |
| headers | Array[(String, String)] | optional |
| early_hints | Array[Array[String]] | optional |
| trailers | Bool | optional |
Returns Self
Methods on Writer
pub fn Writer::new(async (Bytes) -> Unit) -> Self
| Parameter | Type | Default |
|---|---|---|
| type only | async (Bytes) -> Unit | required |
Returns Self
pub fn Writer::trailer(Self, String, String) -> Unit
Add a trailing field, sent after the body when the stream announced trailers.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
| type only | String | required |
Returns Unit
pub fn Writer::trailers(Self) -> Array[(String, String)]
The trailing fields set so far.
Returns Array[(String, String)]
pub async fn Writer::write(Self, Bytes) -> Unit
Send chunk as one piece of the body. An empty chunk is not sent: it would say nothing.
| Parameter | Type | Default |
|---|---|---|
| type only | Bytes | required |
Returns Unit
pub async fn Writer::write_text(Self, String) -> Unit
Send text as UTF-8.
| Parameter | Type | Default |
|---|---|---|
| type only | String | required |
Returns Unit
@templates
Server-side template rendering and the context processors that feed it.
Types
pub type Processor = (@ctx.Context) -> Map[String, Json]
A context processor : the request in, the names every template rendered for it can use.
pub struct Templates { env : @moonpug.Env // private fields }
Templates rendered into HTML responses , over a moonpug environment, which holds the loader, the settings, the filters and the globals.
Every template sees request: its method, url, path, root_path, the first value of each query parameter, the headers and the path params. Given url_for, it also sees url_for(name, **params), which resolves a named route; pass (name, params) => app.url_for(name, params~).
| Field | Type |
|---|---|
| env | @moonpug.Env |
Methods on Templates
pub fn Templates::new(@moonpug.Env, processors? : Array[(@ctx.Context) -> Map[String, Json]], url_for? : (String, Map[String, String]) -> String?) -> Self
| Parameter | Type | Default |
|---|---|---|
| type only | @moonpug.Env | required |
| processors | Array[(@ctx.Context) -> Map[String, Json]] | optional |
| url_for | (String, Map[String, String]) -> String? | optional |
Returns Self
pub fn Templates::response(Self, @ctx.Context, String, context? : Map[String, Json], status? : Int32, media_type? : String, wins? : @jwt.Wins, clash? : @jwt.OnClash[Map[String, Json]]) -> @http.Response raise @spec.Refused
Render the template name into a response TemplateResponse).
A template's names come in three layers: request, then what each processor returns in order, then context. Where a later layer names what an earlier one did, the later one wins by default, the call being the most specific of the three. wins=Base keeps the processors' and ours instead; clash can abort or hand the decision to a callback, which receives the processors' names and the merged ones. url_for is added last, unless a layer already named it.
A template that does not load or does not render raises Refused, which the app answers with a 500 like any other error a handler raises.
| Parameter | Type | Default |
|---|---|---|
| type only | @ctx.Context | required |
| type only | String | required |
| context | Map[String, Json] | optional |
| status | Int32 | optional |
| media_type | String | optional |
| wins | @jwt.Wins | optional |
| clash | @jwt.OnClash[Map[String, Json]] | optional |
Returns @http.Response raise @spec.Refused