messua

A collection of convenience types and functions that might amount to a small web framework sitting atop mist.

Package Version Hex Docs

Messua is a genus of spider, which apparently was itself named after a character from The Jungle Book. Please do not take this as any sort of endorsement of any orientalist or colonialist themes that may appear in Kipling’s work; I just wanted a name vaguely related to webs that probably wouldn’t already be taken.

Introduction

When a piece of technology focuses on a particular solution or style in the face of many alternatives, it is in fashion these days to refer to that piece of technology as being “opinionated”, particularly when describing a programming language, framework, or library. I wouldn’t say that Messua is opinionated so much as I’d say it sees the point of doing things a certain way, and is willing to give that a go. It is based largely on a couple of convenient patterns I have found myself using when implementing backends in Rust and Gleam:

  1. A common Result(Response, Error) type returned by handlers, for which the Error variant gets automatically converted to a response.
  2. A common Request type (injected1 with some server state), passed “down” through layers of middleware, with the aforementioned Result type bubbling back up.
  3. Functions that couple this Result type with Gleam’s use sugar to mimic early returns of Error variants that then get handled with a minimum of ceremony, permitting focus on business logic and an uncluttered happy path.
1

I use the term “injected”, but really it’s more like, “bundled with”. Under the hood, the MRequest is just a wrapper that holds the underlying request (the gleam_http type) and your state.

This library owes a lot to a couple of Rust crates: the axum web server, and the tower middleware crate, particularly its Layer trait. You might even call this package a sort of cozily-sized Gleam version of some of the axum/tower ecosystem.

Approach

Messua provides a sort of mist harness into which it hooks your handler function (and any Layers you might have on top of it). It provides your stack with an MRequest and expects it to return an MResponse (which is just an alias for a Result whose Ok variant is a gleam/http/response.Response, and whose Error variant is messua/err.Err, which gets turned into an actual HTTP response by the harness). It then provides you with a slew of convenience functions for extracting parts of requests, routing, and generating responses.

Messua also provides wrappers around some key things from mist and gleam_http; the idea here is that it’s easier and more convenient to import and use a single package, rather than having to mess around in the guts of three separate packages, wondering which one has the functionality you want.

Examples

There is a growing list of examples in the examples directory; here’s the simplest one:

import messua
import messua/ok
import messua/rr.{type MRequest, type MResponse}

fn handler(_req: MRequest(Nil)) -> MResponse {
  ok.ok()
  |> ok.with_text_body("Hello, World!\n")
  |> Ok()
}

pub fn main() {
  messua.default()
  |> messua.with_binding("localhost")
  |> messua.with_http(8080)
  |> messua.start(handler)
}

A gleam run should be all you need to get the server started; then you can query it and get a response:

~/ $ curl localhost:8080
Hello, World!
Search Document