oaisp/route
A route binds a path and method to a handler and carries the OpenAPI
annotations for that endpoint. One list of routes is the single source of
truth: it drives your running server (via match) and the
generated document (via to_endpoints), so the two can’t
drift.
Annotations are a single OpenApi record — build the default
and spread what you need, mirroring the F# addOpenApi(OpenApiConfig(…)):
route.get("/plants", handle_list_plants)
|> route.with_openapi(OpenApi(
..route.openapi(),
summary: Some("ListPlants"),
tags: ["Portfolio"],
responses: [ResponseBody(200, type_ref("myapp/types", "PlantList"))],
))
oaisp never inspects the handler — Route is generic in it — so oaisp gains
no dependency on wisp, mist, or any server library. match returns the
matched handler and the captured path parameters for you to invoke.
Types
The result of a successful match: the handler to invoke and the
path parameters captured from the request path.
pub type Matched(handler) {
Matched(handler: handler, path_params: List(#(String, String)))
}
Constructors
-
Matched(handler: handler, path_params: List(#(String, String)))
The OpenAPI annotations for a route. Build openapi and spread
to set what you need.
pub type OpenApi {
OpenApi(
summary: option.Option(String),
description: option.Option(String),
operation_id: option.Option(String),
tags: List(String),
path: List(#(String, schema.Schema)),
query: List(QueryParam),
query_record: option.Option(schema.Schema),
request_body: option.Option(schema.Schema),
responses: List(ResponseSpec),
)
}
Constructors
-
OpenApi( summary: option.Option(String), description: option.Option(String), operation_id: option.Option(String), tags: List(String), path: List(#(String, schema.Schema)), query: List(QueryParam), query_record: option.Option(schema.Schema), request_body: option.Option(schema.Schema), responses: List(ResponseSpec), )
A documented query parameter.
pub type QueryParam {
QueryParam(name: String, schema: schema.Schema, required: Bool)
}
Constructors
-
QueryParam(name: String, schema: schema.Schema, required: Bool)
A documented response: a body of a given type, or an empty response.
pub type ResponseSpec {
ResponseBody(status: Int, schema: schema.Schema)
EmptyResponse(status: Int, description: String)
}
Constructors
-
ResponseBody(status: Int, schema: schema.Schema) -
EmptyResponse(status: Int, description: String)
Values
pub fn delete(path: String, handler: handler) -> Route(handler)
A DELETE route at path, served by handler.
pub fn documented(
route: Route(handler),
summary summary: String,
tags tags: List(String),
path path: List(#(String, schema.Schema)),
responses responses: List(ResponseSpec),
) -> Route(handler)
Document an endpoint in one call — the common case of a summary, some tags,
path parameters, and responses, without building an OpenApi
record or wrapping fields in Some:
route.get("/todos/{id}", get_todo)
|> route.documented(
summary: "Get a todo by id",
tags: ["todos"],
path: [#("id", param.string())],
responses: [
ResponseBody(200, type_ref("myapp/types", "Todo")),
ResponseBody(404, type_ref("myapp/types", "Error")),
],
)
It is exactly with_openapi over those four fields, so the
two produce the same endpoint. Reach for the full record when you also need a
description, an operationId, query parameters, a reflected query record, or
a request body.
pub fn get(path: String, handler: handler) -> Route(handler)
A GET route at path, served by handler.
pub fn match(
routes: List(Route(handler)),
method: String,
path_segments: List(String),
) -> Result(Matched(handler), Nil)
Find the first route whose method and path match the request, returning its
handler and the captured path parameters. method is the lower-cased HTTP
method ("get", "post", …); path_segments is the request path split on
/ (e.g. ["todos", "42"]).
pub fn patch(path: String, handler: handler) -> Route(handler)
A PATCH route at path, served by handler.
pub fn post(path: String, handler: handler) -> Route(handler)
A POST route at path, served by handler.
pub fn put(path: String, handler: handler) -> Route(handler)
A PUT route at path, served by handler.
pub fn to_endpoints(
routes: List(Route(handler)),
) -> List(endpoint.Endpoint)
The documented endpoints behind these routes — the input to the document generator. Drops the handlers.