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

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)

A documented endpoint plus the handler that serves it. handler is whatever your framework uses — e.g. fn(wisp.Request, List(#(String, String))) -> wisp.Response.

pub opaque type Route(handler)

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 openapi() -> OpenApi

An empty OpenApi annotation — spread it to set fields.

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.

pub fn with_openapi(
  route: Route(handler),
  config: OpenApi,
) -> Route(handler)

Apply OpenAPI annotations to a route.

Search Document