DEV Community

Alex Spinov
Alex Spinov

Posted on

Rocket Has a Free API — Rust Web Framework That Writes Itself

Rocket is a Rust web framework focused on developer experience. With macro-based routing, built-in form handling, and templating — Rocket makes Rust web development feel as easy as Python.

Why Rocket?

  • Macro-based routing — routes defined with #[get], #[post] attributes
  • Type-safe — request guards validate before your handler runs
  • Built-in — forms, JSON, templates, cookies, sessions
  • Async — fully async since Rocket 0.5

Quick Start

cargo new myapp && cd myapp
cargo add rocket --features json
Enter fullscreen mode Exit fullscreen mode
#[macro_use] extern crate rocket;
use rocket::serde::json::Json;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Message {
    content: String,
}

#[get("/")]
fn index() -> &'static str {
    "Hello, Rocket!"
}

#[get("/hello/<name>")]
fn hello(name: &str) -> Json<Message> {
    Json(Message {
        content: format!("Hello, {}!", name),
    })
}

#[post("/messages", data = "<msg>")]
fn create(msg: Json<Message>) -> Json<Message> {
    msg
}

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

Request Guards

use rocket::request::{self, FromRequest, Request};

struct ApiKey(String);

#[rocket::async_trait]
impl<'r> FromRequest<'r> for ApiKey {
    type Error = ();

    async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
        match req.headers().get_one("X-API-Key") {
            Some(key) if key == "secret" => request::Outcome::Success(ApiKey(key.into())),
            _ => request::Outcome::Forward(rocket::http::Status::Unauthorized),
        }
    }
}

#[get("/protected")]
fn protected(key: ApiKey) -> &'static str {
    "Access granted"
}
Enter fullscreen mode Exit fullscreen mode

Forms

use rocket::form::Form;

#[derive(FromForm)]
struct Login {
    username: String,
    password: String,
}

#[post("/login", data = "<form>")]
fn login(form: Form<Login>) -> String {
    format!("Welcome, {}!", form.username)
}
Enter fullscreen mode Exit fullscreen mode

Database (with rocket_db_pools)

use rocket_db_pools::{Database, sqlx};

#[derive(Database)]
#[database("mydb")]
struct Db(sqlx::PgPool);

#[get("/users")]
async fn users(db: &Db) -> Json<Vec<User>> {
    let users = sqlx::query_as!(User, "SELECT * FROM users")
        .fetch_all(&**db)
        .await
        .unwrap();
    Json(users)
}
Enter fullscreen mode Exit fullscreen mode
# Rocket.toml
[default.databases.mydb]
url = "postgres://localhost/myapp"
Enter fullscreen mode Exit fullscreen mode

Need web scraping in your Rust stack? Check out my Apify actors for data extraction, or email spinov001@gmail.com for custom solutions.

Rocket vs Actix Web vs Axum — what's your pick? Let me know!

Top comments (0)