Introduction
Rust is known for its performance and safety, making it an excellent choice for building web applications. In this tutorial, we will walk through creating a basic REST API using Rust, utilizing the actix-web framework. By the end of this guide, you will have a simple API that can handle basic CRUD (Create, Read, Update, Delete) operations.
Prerequisites
Before we begin, ensure you have the following installed:
- Rust (you can install it from rustup.rs)
- Cargo (comes with Rust)
Setting Up the Project
First, let's create a new Rust project:
cargo new rust-rest-api
cd rust-rest-api
Open the
Cargo.toml file and add the dependencies:
[dependencies]
actix-web = "4"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
uuid = "1"
Creating the Main File
Let's start by creating a simple server. Open
src/main.rs and modify it as follows:
use actix_web::{web, App, HttpServer, Responder, HttpResponse};
use serde::{Serialize, Deserialize};
use uuid::Uuid;
#[derive(Serialize, Deserialize)]
struct Item {
id: Uuid,
name: String,
}
async fn greet() -> impl Responder {
HttpResponse::Ok().body("Hello, world!")
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/", web::get().to(greet))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Run the server with:
cargo run
Open your browser and navigate to
http://127.0.0.1:8080. You should see "Hello, world!".
Adding CRUD Endpoints
Now, let's expand our API to handle CRUD operations for Item.
Create Item:
async fn create_item(item: web::Json<Item>) -> impl Responder {
HttpResponse::Created().json(item.into_inner())
}
Read Item:
async fn get_item(id: web::Path<Uuid>) -> impl Responder {
HttpResponse::Ok().json(Item {
id: *id,
name: String::from("Sample Item"),
})
}
Update Item:
async fn update_item(id: web::Path<Uuid>, item: web::Json<Item>) -> impl Responder {
HttpResponse::Ok().json(Item {
id: *id,
name: item.name.clone(),
})
}
Delete Item:
async fn delete_item(id: web::Path<Uuid>) -> impl Responder {
HttpResponse::NoContent().finish()
}
Update your main function to include these routes:
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/", web::get().to(greet))
.route("/item", web::post().to(create_item))
.route("/item/{id}", web::get().to(get_item))
.route("/item/{id}", web::put().to(update_item))
.route("/item/{id}", web::delete().to(delete_item))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Testing the API
You can test the API using curl or a tool like Postman.
Create Item:
curl -X POST http://127.0.0.1:8080/item -H "Content-Type: application/json" -d '{"id": "550e8400-e29b-41d4-a716-446655440000", "name": "NewItem"}'
Get Item:
curl http://127.0.0.1:8080/item/550e8400-e29b-41d4-a716-446655440000
Update Item:
curl -X PUT http://127.0.0.1:8080/item/550e8400-e29b-41d4-a716-446655440000 -H "Content-Type: application/json" -d '{"name": "UpdatedItem"}'
Delete Item:
curl -X DELETE http://127.0.0.1:8080/item/550e8400-e29b-41d4-a716-446655440000
Conclusion
Congratulations! You've created a basic REST API using Rust and actix-web. This tutorial covered setting up a Rust project, creating a simple server, and implementing basic CRUD operations. From here, you can expand the API with more features and robust error handling.