DEV Community

Cover image for Getting Started with Rocket and Rust for REST APIs (Building a To-Do App)
Jaken Herman
Jaken Herman

Posted on • Originally published at jakenherman.com

Getting Started with Rocket and Rust for REST APIs (Building a To-Do App)

In this blog post, we’ll begin building a simple to-do application using Rust and the Rocket web framework. Rocket provides a high-level API for building web applications and REST APIs, making it a great choice for developers who want to get up and running quickly. If you make it to the end of this post (and the end of this three-part series, you’ll have a basic REST API set up with Rocket that handles HTTP requests - which should set up a solid foundation for you to venture forward in making a fully-fledged to-do application (I know, I know - who needs another to-do application?)

What You'll Learn

  • Setting up a Rust project and adding Rocket as a dependency.
  • Creating a basic Rocket server.
  • Handling HTTP GET requests.

Prerequisites

Make sure you have Rust installed

💡

You can skip the project setup step, if you’d like, by cloning my GitHub repository, just make sure that if you do, you’re on the correct branch for this specific post. The branch is post-1. So once you’ve cloned, be sure to run git checkout post-1.


Setting up the Project

Let’s start by creating a new Rust project for the to-do app. I’m going to name mine dooly. You should modify the command below to replace dooly with whatever you’d like to name your application. Run the following commands:

cargo new dooly && cd dooly
Enter fullscreen mode Exit fullscreen mode

Next, we’ll need to add a few dependencies. Run cargo add rocket serde serde_json. Now, open the Cargo.toml file and add modify your dependencies to include the derive and json features, like so:

[dependencies]
rocket = { version = "0.5.1", features = ["json"] }
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
Enter fullscreen mode Exit fullscreen mode

Setting Up a Basic Rocket Server

With the dependencies ready, let's write our initial Rocket server. Open src/main.rs and replace the content with the following:

#[macro_use] extern crate rocket;

#[get("/")]
fn index() -> &'static str {
    "Welcome to the Rust To-Do API!"
}

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

Let’s break this down:

  • #[macro_use] extern crate rocket; is required to use Rocket’s macros.
  • #[get("/")] is an attribute that defines a route handler for GET requests to the root (/) of the server.
  • rocket::build() initializes the Rocket server, and .mount("/", routes![index]) mounts the route (index()) at the root URL (/).

Now, run the server using:

cargo run
Enter fullscreen mode Exit fullscreen mode

You should see Rocket's launch sequence, and the server will start on localhost:8000:

🚀 Rocket has launched from http://localhost:8000
Enter fullscreen mode Exit fullscreen mode

Open your browser and visit http://localhost:8000. You should see:

Welcome to the Rust To-Do API!
Enter fullscreen mode Exit fullscreen mode

Handling Basic GET Requests for To-Do Items

Now let’s add a route to retrieve a list of to-do items. For now, we’ll return a static list of hardcoded items in JSON format. This can be supplemented with a list of items retrieved from a database or other storage method at a later time.

Replace the contents of src/main.rs with the following code:

#[macro_use] extern crate rocket;
use rocket::serde::{Serialize, json::Json};

#[derive(Serialize)]
struct TodoItem {
    id: u32,
    title: "String,"
    completed: bool,
}

#[get("/todos")]
fn get_todos() -> Json<Vec<TodoItem>> {
    let todos = vec![
        TodoItem { id: 1, title: "\"Learn Rust\".to_string(), completed: false },"
        TodoItem { id: 2, title: "\"Build a REST API\".to_string(), completed: false },"
    ];
    Json(todos)
}

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

What’s new?

  • TodoItem: A struct representing a to-do item. We derive Serialize so it can be converted into JSON.
  • Json<Vec<TodoItem>>: Rocket's JSON type is used to return a vector of TodoItem instances as JSON.
  • The get_todos route is defined with the #[get("/todos")] macro, and it returns a static list of two to-do items.

Now, restart the server:

cargo run
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:8000/todos on your browser (or use a tool like Insomnia or Postman - both great options) and you should see a JSON response:

[
  {
    "id": 1,
    "title": "Learn Rust",
    "completed": false},
  {
    "id": 2,
    "title": "Build a REST API",
    "completed": false}
]
Enter fullscreen mode Exit fullscreen mode

Breaking Down Rocket’s Routing and Response

So let’s go over what we really did here. Rocket makes it simple to define routes. Here's how we defined the /todos route:

  • #[get("/todos")]: This specifies the HTTP method (GET) and the path (/todos) the route responds to.
  • Json(todos): We wrap the list of TodoItem structs in Json to automatically serialize it into JSON for the response.

Rocket also handles other HTTP methods like POSTPUT, and DELETE, which we’ll explore in future posts.


In this first post of this three-part series, we’ve set up a simple Rocket server and created a basic route to return a list of to-do items. In the next post, we’ll implement functionality to add, update, and delete to-do items, allowing users to interact with the API using different HTTP methods.

Top comments (0)