Your first application
Every box office starts with a line-up. In this chapter, we'll show tonight's concerts twice: in the terminal for the staff, and on the web for everyone else. We'll keep the line-up in code for now. The container moves it into a file, and Database into PostgreSQL.
The line-up
The line-up is a singleton: an object Margaret creates once and shares with everyone who needs it.
use singleton;
;
A command for the staff
Commands are singletons too. This one asks for the Lineup in its constructor:
use Arc;
use CommandOutcome;
use console_command;
use constructor;
use process;
use singleton;
use crateLineup;
Register the modules as usual, and run it:
$ cargo run -- lineup
The Midnight Owls
Paper Lanterns
Velvet StaticNotice what you didn't write: argument parsing, help text, or any code that creates the Lineup. Margaret generated all of it.
A page for everyone else
Now let's put the line-up on the web. A route is a singleton with #[responds_to_http]. The HTTP method is a typed RouteMethod, so a typo in it doesn't compile:
use Arc;
use Response;
use constructor;
use process;
use responds_to_http;
use singleton;
use RouteMethod;
use crateLineup;
Add the serving crates to Cargo.toml, switch main to Tokio as shown in Installation, and start the server:
[dependencies]
anyhow = "1.0"
clap = "4.5"
margaret = "0.4"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
tokio-util = "0.7"
trzcina = "0.4"$ cargo run -- serve --public-addr 127.0.0.1:8080 --public-url http://127.0.0.1:8080$ curl http://127.0.0.1:8080/concerts
The Midnight Owls
Paper Lanterns
Velvet StaticWhere did --public-addr and --public-url come from? The route said server = "public", so Margaret gave that server its own address and URL. The URL is an origin, like https://tickets.example.com, and Margaret refuses one with a path.
Break something
Let's make a mistake on purpose. Ask the route for a city parameter that its path doesn't have:
city: String,Run cargo build, and Margaret refuses:
Error: Http { source: Binding { source: RouteParameterNotInPath { subject: "responder 'crate::routes::public::list_concerts::ListConcerts'", parameter: "city", path: "/concerts" } } }That's Margaret's promise: mistakes in how your application fits together show up while you build, long before anyone buys a ticket.
Next steps
Before moving on, How Margaret works shows what Margaret generated for these two files. Then the container takes the line-up out of the code.