DEV Community

Cover image for Rocket: The Rust Web Framework Built Around Ergonomics
tdk-cli
tdk-cli

Posted on

Rocket: The Rust Web Framework Built Around Ergonomics

Most Rust web frameworks ask you to compose routing and middleware explicitly. Rocket asks you to describe what a route expects, and then gets out of the way. You write a route with an attribute, declare the types of its inputs, and the framework checks and converts them before your function runs. For many developers, that difference is the reason they choose it.

The core idea

A Rocket route looks like this:

#[macro_use] extern crate rocket;

#[get("/health")]
fn health() -> &'static str {
    "ok"
}

#[launch]
fn rocket() -> _ {
    rocket::build().mount("/", routes![health])
}
Enter fullscreen mode Exit fullscreen mode

The #[get] attribute declares the method and path. The routes! macro collects them, and #[launch] generates the entry point. Inputs follow the same pattern: a path parameter, a query, or a JSON body is declared in the function signature, and Rocket parses it into the declared type.

Request guards

Request guards are the most distinctive feature. A guard is a type that Rocket builds from the incoming request. If the guard fails, the route does not run, and the framework returns the appropriate error. An authentication check, for example, can be a guard type that a handler simply requires in its signature.

The benefit is that the rule lives with the route. A reader sees that a handler needs an authenticated user from the function signature alone, not from a middleware registered somewhere else.

Configuration

Rocket reads its settings from a config file and environment variables, with separate profiles for development and production. Port, address, and secret keys are configured in one place. This makes it straightforward to keep the same binary running across environments.

Trade-offs

  • Stable Rust. Rocket's current releases run on stable Rust, which removes a common barrier for teams that do not want a nightly toolchain.
  • Macro-heavy style. The attributes make routes easy to read, but they also hide some of what happens at compile time. Newcomers sometimes struggle when a macro error points at generated code.
  • Smaller ecosystem than the most common alternatives. Fewer third-party middleware crates exist for Rocket than for tower-based frameworks, so some integrations may need more code.

Testing

Rocket provides a local client that builds the application without binding a port, so tests can send requests and assert on the responses. This keeps the test suite fast and avoids port conflicts when several tests run at once.

When to pick it

Rocket fits well when you want typed, declarative routes, a clear configuration story, and a framework that feels approachable on day one. It suits internal APIs, prototypes that may become production services, and teams that value readable route definitions.

If your service needs a large set of tower middleware, or you want the framework closest to the runtime, an axum or actix-web project may suit better.

Running it in a multi-service system

A Rocket service still needs a health route, a port taken from its configuration, and a bind address that accepts outside traffic. Build a release binary in a container, and keep the process non-root.

TDK CLI generates Rust backends with axum, not Rocket. To run a Rocket service inside a TDK stack, containerise it and register it as a bring-your-own resource, so TDK still handles routing and the health check.

Top comments (0)