Production grade api with Rocket & Rust
You’ll need to install Rust and the Rocket framework.
curl https://sh.rustup.rs -sSf | sh
Then install Rocket:
cargo install rocket
Create a new Rocket project:
rocket new my-project
This will create a Cargo.toml and src/main.rs. Cargo.toml contains project metadata and dependencies. src/main.rs contains your Rocket app.
2. Handling Requests
Define routes with the route
attribute:
#[get("/hello/<name>")]
fn say_hello(name: String) -> String {
format!("Hello, {}!", name)
}
This will match GET requests to /hello/<name>
and extract the name parameter.
You can also have POST requests:
#[post("/posts", format = "application/json", data = "<new_post>")]
fn create_post(new_post: Json<Post>) -> Json<Post> {
// Create post
Json(new_post.into_inner())
}
Use request guards to validate requests, access request data like query parameters, forms, and JSON.
3. Responding
Return strings, JSON, or templates:
#[get("/")]
fn index() -> Template {
Template::render("index", ...) // Load a Twig template
}
#[get("/posts")]
fn posts() -> Json<Vec<Post>> {
let posts = ...; // Load list of posts from DB
Json(posts)
}
Set status codes and headers:
fn not_found() -> status::NotFound<String> {
status::NotFound("Nothing found".into())
}
fn create_post(post: Json<Post>) -> (status::Created, json::Json<Post>) {
...
}
Redirect with status::SeeOther
:
fn old_route() -> status::SeeOther {
status::SeeOther(uri!(new_route))
}
4. State management
Rocket gives you managed state to store database pools, caches, etc. You can access these in your routes:
#[get("/posts")]
fn list_posts(db: State<DbConn>) -> Json<Vec<Post>> {
let posts = db.run(|c| c.load_posts()).unwrap();
Json(posts)
}
You can use databases like Diesel or rusqlite and cache with r2d2. Cookies and sessions can be managed with rocket_contrib.
5. Deployment
Build a release with cargo build --release
. Host on AWS, GCP, Azure, Digital Ocean, etc. Configure Rocket for production with:
[production]
port = 8000
workers = 4
secret_key = "my_secret_key"
Set up health checks and logging.
6. Testing
Unit test with Rust’s std::test:
#[test]
fn test_say_hello() {
assert_eq!(say_hello("John"), "Hello, John!");
}
Integration test with Rocket:
#[test]
fn test_list_posts() {
let client = Client::new(App::new().manage(MockDb::new())).unwrap();
let response = client.get("/posts").dispatch();
assert_eq!(response.body_string(), "[]");
}
Property based testing with proptest. Mock external services.
7. Additional topics
Authentication with JWTs or sessions, authorization, file uploading, CORS, rate limiting, async/await, and more!