Introduction
Margaret is an opinionated Rust framework for web services and console applications. Its big idea: the compiler should check how your application fits together, just like it checks your types.
You describe your application with attributes. While your project builds, Margaret verifies that every piece connects, and generates the code that wires them together.
Throughout these docs, we'll build a box office that sells concert tickets. It starts as a single page and grows into a small platform: a PostgreSQL database, live seat availability, payments, sign-in with email links and Google, ticket scanners at the door, and an OpenID Connect provider that other apps sign fans in with.
A quick look
Here's the page for a single concert:
use Response;
use process;
use responds_to_http;
use singleton;
use RouteMethod;
use crateConcertWithVenue;
;
Before this code ever runs, Margaret makes sure that:
the
{concert}segment exists in the path,ConcertWithVenuecan be loaded from the database by the concert's primary key, venue included, in a single query,nothing else answers
GET /concerts/{concert}.
Ask for a parameter the path doesn't have, and the build stops right there:
Error: Http { source: Binding { source: RouteParameterNotInPath { subject: "responder 'crate::routes::public::show_concert::ShowConcert'", parameter: "slug", path: "/concerts/{concert}" } } }What makes Margaret different
Checked while you build
Missing dependencies, dependency cycles, clashing routes, links to routes that don't exist, unknown views, missing assets, and WebSocket messages nobody handles are all build errors. So are database queries that would scan a table without an index, read rows without a limit, or load related rows one by one.
Exactly one way to do each thing
Margaret never picks a winner for you. When two responders answer GET /concerts/{concert}, that's a build error. Every task has a single, obvious place in your code.
Everything is explicit
Pieces connect through attributes and types, and Margaret identifies each one by its full path. Two ShowConcert structs in different modules are simply two different routes, and you can name things however you like.
Generated code you can read
Margaret writes plain Rust into a margaret module of your crate: the container, the command line, the servers, the queries for your models. You can open it, read it, and step through it. How Margaret works shows what's inside.
Settings live where they're used
When the box office needs a mail server, the constructor of the mailer asks for its address. Margaret turns those requests into typed command line flags and environment variables.
Built for services
Several HTTP servers in one process, typed WebSocket sessions, a PostgreSQL ORM, browser sessions, sign-in with any OpenID Connect provider, an OpenID Connect provider of your own, OAuth clients, mutual TLS between services, and frontend assets embedded in your binary all come included.
Is it for you?
Margaret trades flexibility for guarantees. If you like to wire things by hand or pick handlers at runtime, it will feel strict. If you'd rather have the compiler catch mistakes before you deploy, you'll feel right at home.
Margaret 0.x is an early release. APIs may change between minor versions.