How to Write a REST API in Rust in 30 Minutes: A Practical Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Rust for REST API?

Rust is a modern systems programming language that combines the performance of C++ with memory safety. In recent years, it has been actively used for building high-load web services and REST APIs. In this guide, we will create a full-fledged REST API in Rust using the Actix-web framework in 30 minutes.

Why choose Rust for REST API?

  • Performance: Rust compiles to native code and does not use a garbage collector, providing maximum request processing speed.
  • Safety: The ownership and borrowing system eliminates entire classes of memory-related errors.
  • Scalability: Actix-web is one of the fastest web frameworks in the world, capable of handling millions of requests per second.

By the end of this article, you will have a ready-made project with several endpoints, error handling, and a structure for further expansion.



Step 1: Project Setup and Dependency Installation

First, let's create a new Cargo project. Open your terminal and run:

cargo new rust_rest_apicd rust_rest_api

Now open the Cargo.toml file and add the following dependencies:

[dependencies]actix-web = "4"serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"tokio = { version = "1", features = ["full"] }uuid = { version = "1.0", features = ["v4", "serde"] }

Let's break down what each library does:

  • actix-web — the main web framework for creating an HTTP server.
  • serde / serde_json — serialization and deserialization of data into JSON format.
  • tokio — an asynchronous runtime required for Actix to work.
  • uuid — generation of unique identifiers for our entities.

Run cargo build to download all dependencies. This will take some time on the first run.



Step 2: Creating the Data Model and Storage

Our API will manage a list of tasks (a TODO application). Let's create a simple model. Open src/main.rs and add the following code:

use actix_web::{web, App, HttpServer, HttpResponse, middleware::Logger};use serde::{Deserialize, Serialize};use std::sync::Mutex;use uuid::Uuid;

// Task model#[derive(Debug, Serialize, Deserialize, Clone)]struct Task { id: Uuid, title: String, completed: bool,}

// Request to create a task#[derive(Debug, Deserialize)]struct CreateTaskRequest { title: String,}

// Task storage (in memory)struct AppState { tasks: Mutex>,}

We use Mutex for thread-safe data access. In a real project, you would replace this with a database, but this option works for demonstration purposes.

Now let's add a function to initialize the application state:

fn init_tasks() -> Vec {    vec![        Task {            id: Uuid::new_v4(),            title: "Learn Rust".to_string(),            completed: false,        },        Task {            id: Uuid::new_v4(),            title: "Write REST API".to_string(),            completed: true,        },    ]}


Step 3: Implementing CRUD Endpoints

Now let's create the main handlers for our REST API. Add the following code after the model declarations:



GET /tasks — get a list of all tasks

async fn get_tasks(data: web::Data<AppState>) -> HttpResponse {    let tasks = data.tasks.lock().unwrap();    HttpResponse::Ok().json(tasks.clone())}


POST /tasks — create a new task

async fn create_task(    data: web::Dat                

Blogs

Book Recommendations