Backend Development 10 min read

Build a Fast, Safe Rust Microservice with Actix-web and SQLite

Learn how to create a simple, high‑performance Rust microservice using Actix‑web, Serde, and SQLite, covering environment setup, project structure, core code for CRUD operations, and testing commands, while highlighting Rust’s memory safety, speed, and low runtime overhead.

Architecture Development Notes
Architecture Development Notes
Architecture Development Notes
Build a Fast, Safe Rust Microservice with Actix-web and SQLite

In modern software development, microservice architecture has become a mainstream method for building scalable, maintainable applications. Rust, as a systems programming language, offers high performance, memory safety, and strong concurrency, making it an increasingly popular choice for microservice development. This article details how to develop a simple Rust microservice and covers the necessary technical details.

Why Choose Rust for Microservice Development?

Rust provides several advantages:

Memory safety : Rust’s ownership system prevents data races and memory bugs, improving stability and security.

High performance : Without a garbage collector, Rust compiles to native code with performance comparable to C/C++.

No runtime overhead : Rust’s minimal runtime makes it ideal for low‑latency, high‑concurrency microservices.

Strong type system : Rust’s type system catches many errors at compile time, enhancing maintainability.

Creating a Simple Rust Microservice

This article builds a simple web microservice that supports basic CRUD (Create, Read, Update, Delete) operations. It uses actix-web to handle HTTP requests, serde for JSON serialization/deserialization, and SQLite as the database.

Environment Setup

First, ensure the Rust toolchain is installed:

<code>$ rustc --version</code>

If not installed, visit the official Rust website for installation instructions.

Next, create a new Rust project:

<code>$ cargo new rust_microservice
$ cd rust_microservice</code>

Adding Dependencies

Add the following dependencies to Cargo.toml :

<code>[dependencies]
actix-web = "4.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
sqlx = { version = "0.5", features = ["sqlite", "runtime-actix-native-tls"] }
env_logger = "0.9"
tokio = { version = "1", features = ["full"] }
</code>

Project Structure

The project consists of two main parts:

Model : defines data structures.

Handler : processes HTTP requests and interacts with the database.

Create the following directory layout:

<code>src/
├── main.rs
├── model.rs
└── handler.rs
</code>

Writing main.rs

Configure the Actix‑web application and start the HTTP server in src/main.rs :

<code>use actix_web::{web, App, HttpServer};
use env_logger::Env;
use sqlx::SqlitePool;

mod model;
mod handler;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init_from_env(Env::default().default_filter_or("info"));

    // Connect to SQLite database
    let pool = SqlitePool::connect("sqlite:database.db").await.expect("Failed to connect to the database");

    // Start HTTP server
    HttpServer::new(move || {
        App::new()
            .data(pool.clone())
            .route("/items", web::post().to(handler::create_item))
            .route("/items", web::get().to(handler::get_items))
            .route("/items/{id}", web::get().to(handler::get_item))
            .route("/items/{id}", web::put().to(handler::update_item))
            .route("/items/{id}", web::delete().to(handler::delete_item))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}
</code>

Writing model.rs

Define the data structure and database mapping in src/model.rs :

<code>use serde::{Deserialize, Serialize};
use sqlx::FromRow;

#[derive(Serialize, Deserialize, FromRow)]
pub struct Item {
    pub id: i32,
    pub name: String,
    pub description: String,
}
</code>

Writing handler.rs

Implement the CRUD handlers in src/handler.rs :

<code>use actix_web::{web, HttpResponse};
use sqlx::{SqlitePool, query_as};
use crate::model::Item;

pub async fn create_item(pool: web::Data<SqlitePool>, item: web::Json<Item>) -> HttpResponse {
    let result = sqlx::query("INSERT INTO items (name, description) VALUES (?, ?)")
        .bind(&item.name)
        .bind(&item.description)
        .execute(pool.get_ref())
        .await;

    match result {
        Ok(_) => HttpResponse::Ok().json(item.0),
        Err(e) => HttpResponse::InternalServerError().body(format!("Error: {}", e)),
    }
}

// Implementations for get_items, get_item, update_item, delete_item follow a similar pattern.
</code>

Running and Testing

Create the SQLite database file database.db at the project root and create the table:

<code>CREATE TABLE items (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    description TEXT NOT NULL
);
</code>

Run the project:

<code>$ cargo run</code>

Test the API with curl commands:

Create an item: curl -X POST http://127.0.0.1:8080/items -H "Content-Type: application/json" -d '{"name":"item1","description":"description1"}'

Get all items: curl http://127.0.0.1:8080/items

Get a single item: curl http://127.0.0.1:8080/items/1

Update an item: curl -X PUT http://127.0.0.1:8080/items/1 -H "Content-Type: application/json" -d '{"name":"updated item","description":"updated description"}'

Delete an item: curl -X DELETE http://127.0.0.1:8080/items/1

Conclusion

By following these steps, we have successfully built a simple Rust microservice application. The article demonstrates key Rust components and techniques for microservice development. Future extensions can include authentication, additional database operations, and logging, leveraging Rust’s performance and safety for robust microservice architectures.

Backend DevelopmentrustSQLiteCRUDMicroserviceActix-web
Architecture Development Notes
Written by

Architecture Development Notes

Focused on architecture design, technology trend analysis, and practical development experience sharing.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.