messua/rr

Requests and Responses.

Types

Naturally, a function that accepts an MRequest and returns an MResponse is considered a request Handler.

pub type Handler(t) =
  fn(MRequest(t)) -> MResponse

A Layer is a Handler with another “inner” Handler it can optionally pass an incoming request through. This inner handler may itself be another layer; it is possible to form stacks arbitrarily deep this way (see the documentation for stack for an example of this).

(The inspiration for this particular type is the tower-layer Rust crate.)

Examples

A layer that logs requests to stdout might look like this:

import gleam/int
import gleam/io
import gleam/string_builder

import gleam/http

fn handler(req: MRequest(State)) -> MResponse {
// ...Routing and handling goes here.  
}

fn log_layer(req: MRequest(State), next: Handler(State)) -> MResponse {
  // Get source, method, path from request.
  let source = case info(req) {
    Ok(info) -> string_builder.from_strings([
      string.inspect(info.ip_address), ":", int.to_string(info.port)
    ])
    Error(_) -> string_builder.from_string("[ source ??? ]")
  }
  
  let inner_req = inner(req)
  let url = string_builder.from_strings([
    string.inspect(inner_req.method),
    " ",
    string.inspect(inner_req.path)
  ])

  // Call inner handling function, get response.
  let mresp = next(req)

  // Note response status.
  let result_msg = case mresp {
    Ok(resp) -> string_builder.from_string(int.to_string(resp.status))
    Err(e) -> string_builder.from_string(int.to_string(e.status))
  }

  // Print a request log entry with the source, method, path fo the
  // request and the status code of the associated response.
  string_builder.append(source, " ")
  |> string_builder.append_builder(url)
  |> string_builder.append(" ")
  |> string_builder.append(result_msg)
  |> string_builder.to_string()
  |> io.println()

  // Return the response.
  mresp
}

make_mist_handler(
  state,
  fn(req) { log_layer(req, handler) }
)
pub type Layer(t) =
  fn(MRequest(t), Handler(t)) -> MResponse

A request with some user-defined server state.

You should never have to manually construct these; they will be constructed by the function returned by make_mist_handler, below.

pub opaque type MRequest(t)

A result type with Errors that will automatically become responses.

pub type MResponse =
  Result(response.Response(mist.ResponseData), err.Err)

Functions

pub fn info(req: MRequest(a)) -> Result(ConnectionInfo, Nil)

Get the underlying connection’s ConnectionInfo.

pub fn inner(req: MRequest(a)) -> Request(Connection)

Access the underlying Request.

pub fn make_mist_handler(
  state: a,
  handle: fn(MRequest(a)) -> Result(Response(ResponseData), Err),
) -> fn(Request(Connection)) -> Response(ResponseData)
pub fn state(req: MRequest(a)) -> a

Retrieve the state that’s been injected into the MRequest.

Search Document