messua
A collection of convenience types and functions that might amount to a small web framework sitting atop mist.
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:
- A common
Result(Response, Error)type returned by handlers, for which theErrorvariant gets automatically converted to a response. - A common
Requesttype (injected1 with some server state), passed “down” through layers of middleware, with the aforementionedResulttype bubbling back up. - Functions that couple this
Resulttype with Gleam’susesugar to mimic early returns ofErrorvariants that then get handled with a minimum of ceremony, permitting focus on business logic and an uncluttered happy path.
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!