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
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"
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])
}
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
You should see Rocket's launch sequence, and the server will start on localhost:8000
:
🚀 Rocket has launched from http://localhost:8000
Open your browser and visit http://localhost:8000
. You should see:
Welcome to the Rust To-Do API!
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])
}
What’s new?
-
TodoItem
: A struct representing a to-do item. We deriveSerialize
so it can be converted into JSON. -
Json<Vec<TodoItem>>
: Rocket's JSON type is used to return a vector ofTodoItem
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
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}
]
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 ofTodoItem
structs inJson
to automatically serialize it into JSON for the response.
Rocket also handles other HTTP methods like POST
, PUT
, 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)