messua/ok

Helpers for building responses.

All body-adding functions set an appropriate Content-Type header unless otherwise noted.

You shouldn’t need to set the Content-Length header; that’ll get set properly and automatically.

Functions

pub fn compress_body(
  resp: Response(ResponseData),
) -> Response(ResponseData)

Compress a response body using deflate.

This sets the Content-Encoding header, but you should still make sure a Content-Type has been set.

Currently, this only works with bodies you have set yourself (i.e., using one of the with_xxx_body() functions); it will not have any effect on files sent with serve_file() or ‘serve_dir()’.

pub fn ok() -> Response(ResponseData)

Create a new, empty 200 OK response.

pub fn serve_dir(
  dir: String,
  subsegments: List(String),
) -> Result(Response(ResponseData), Err)

Serve a file from the given directory.

The subsegments argument should be a list of “path segments” that to be appended to the dir argument to form the final on-disk path of the file to send. If the path isn’t found, or there’s otherwise a problem sending the file, a 404 error will be sent.

Like serve_file(), this does not (as of yet) work in conjunction with compress_body().

Examples

This is meant to be used in conjunction with handle.path_segments() and pattern matching:

import messua/errs
import messua/handle
import messua.ok

fn handle_api_request(req: MRequest, segments: List(String)) -> MResponse {
  // Your important proprietary SaaS biznass goes here.
}

fn router(req: MRequest(state)) -> MResponse {
  case handle.path_segments(req) {
     ["api", ..rest] -> handle_api_request(req, rest)
     ["static", ..rest] -> ok.serve_dir("/app/assets/static", rest)
     [] -> ok.serve_file("/app/assets/index.html")
     _ -> errs.not_found()
  }
}
pub fn serve_file(
  path: String,
) -> Result(Response(ResponseData), Err)

Serve the given file as the body of the request.

Content-Type will be guessed and set by file extension using the marceau package; if the supplied path isn’t found (or can’t be read), a 404 error will be sent instead.

Please note that compress_body() will not work with this function (it won’t cause an error, it just won’t compress anything). This function uses some lower-level Erlang magic to send the file with low overhead, and I don’t yet know enough Erlang1 to compress data at that level.

1

And by “enough”, I mean “any”.

TODO: Learn some Erlang and do better.

pub fn with_binary_body(
  resp: Response(ResponseData),
  body: BytesBuilder,
) -> Response(ResponseData)

Add a body of raw bytes.

This sets the Content-Type to application/octet-stream; use with_header() if you want a different Content-Type.

pub fn with_header(
  resp: Response(ResponseData),
  name: String,
  value: String,
) -> Response(ResponseData)

Add the given header to the response.

pub fn with_json_body(
  resp: Response(ResponseData),
  body: Json,
) -> Response(ResponseData)

Add a Json body (as produced by the gleam_json package).

pub fn with_text_body(
  resp: Response(ResponseData),
  body: String,
) -> Response(ResponseData)

Add a plain-text body.

Search Document