Rust has become a popular language for system-level programming due to its memory safety and performance features. However, it is also making strides in the web development realm.
This article will guide you through the process of building your first web application using Rust. We’ll use the Actix framework, known for its speed and robustness, along with the Diesel ORM for database interactions.
Table of Contents
1. Introduction
In this blog, we’ll build a simple web application using Rust. The application will allow users to view and add items to a list. We’ll use Actix for the web framework and Diesel for the database interaction. This example will help you understand the basics of Rust web development and get you started with building more complex applications.
2. Setting Up the Development Environment
Installing Rust
First, you need to have Rust installed on your system. If you don’t have it already, you can install it using rustup, which is an installer for the Rust programming language.
Open your terminal and run:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Follow the on-screen instructions to complete the installation. After installation, ensure that It is properly installed by checking its version:
rustc --version
Setting Up Cargo
Cargo is Rust’s package manager and build system. It should be installed automatically with it. You can check Cargo’s version with:
cargo --version
Installing Necessary Tools
For this tutorial, you’ll need additional tools:
- Actix Web: A powerful, pragmatic web framework.
- Diesel: A safe and extensible ORM and Query Builder.
- SQLite: A lightweight database for simplicity.
You can install SQLite through your package manager. For example, on Debian-based systems:
sudo apt-get install sqlite3
3. Creating a New Rust Project
Now, let’s create a new project for our web application. Go to your terminal, navigate to that directory where you want to create your project and run:
cargo new rust_web_app
cd rust_web_app
This command creates a new directory called rust_web_app
with the necessary Rust project files.
4. Adding Dependencies
Edit the Cargo.toml
file to add the dependencies you need for Actix and Diesel. Open Cargo.toml
and add the following sections:
[dependencies]
actix-web = "4.0"
diesel = { version = "2.0", features = ["sqlite"] }
dotenv = "0.15"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
These dependencies will allow us to use Actix for the web server, Diesel for ORM, and Serde for JSON serialization.
5. Building the Web Server with Actix
Defining Routes
Create a new file named main.rs
in the src
directory (it should already exist if you followed the project creation steps). Start by defining the basic structure of your Actix web server:
use actix_web::{web, App, HttpServer, HttpResponse, Responder};
async fn index() -> impl Responder {
HttpResponse::Ok().body("Hello, welcome to Rust web app!")
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/", web::get().to(index))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
In this code, we define a single route /
that returns a simple welcome message.
Setting Up a Simple Handler
You can add more routes and handlers as needed. For instance, to create a handler for adding items to a list, you might set up a POST route:
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct Item {
name: String,
}
async fn add_item(item: web::Json<Item>) -> impl Responder {
HttpResponse::Created().json(item.into_inner())
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/", web::get().to(index))
.route("/add", web::post().to(add_item))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
6. Setting Up a Database with Diesel

Configuring Diesel
First, add Diesel CLI to your system for database management:
cargo install diesel_cli --no-default-features --features sqlite
Create a .env
file in your project root directory to specify your database URL:
DATABASE_URL=db.sqlite
Next, set up Diesel for your project:
diesel setup
Creating Migrations
To create a table for storing items, you’ll need to create a migration:
diesel migration generate create_items
Edit the generated migration files in the migrations
folder to define the schema for your items:
-- up.sql
CREATE TABLE items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL
);
-- down.sql
DROP TABLE items;
Apply the migration with:
diesel migration run
Writing Models
Create a new file models.rs
in the src
directory to define your data model:
use diesel::prelude::*;
use diesel::sqlite::SqliteConnection;
use serde::{Deserialize, Serialize};
#[derive(Queryable, Serialize, Deserialize)]
pub struct Item {
pub id: i32,
pub name: String,
}
#[derive(Insertable, Deserialize, Serialize)]
#[table_name = "items"]
pub struct NewItem<'a> {
pub name: &'a str,
}
7. Connecting the Web Server to the Database
Update your main.rs
to include database connection and CRUD operations. First, configure Diesel in main.rs
:
use diesel::prelude::*;
use diesel::sqlite::SqliteConnection;
use actix_web::{web, App, HttpServer, HttpResponse, Responder};
use crate::models::{Item, NewItem};
use dotenv::dotenv;
use std::env;
async fn add_item(
item: web::Json<Item>,
pool: web::Data<SqliteConnection>,
) -> impl Responder {
use crate::schema::items::dsl::*;
let new_item = NewItem { name: &item.name };
let connection = pool.get().expect("Failed to get connection from pool");
diesel::insert_into(items)
.values(&new_item)
.execute(&connection)
.expect("Error saving new item");
HttpResponse::Created().json(item.into_inner())
}
Make sure to set up the database pool and pass it to your handlers.
8. Running the Application
You can now run your web application with:
cargo run
Visit http://127.0.0.1:8080
in your web browser to see the welcome message, and use a tool like curl
or Postman to test adding items.
9. Testing and Debugging
Test your application thoroughly to ensure it works as expected. You can use Rust’s built-in test framework to write unit tests for your handlers and database interactions.
For debugging, consider using the dbg!
macro or more advanced debugging tools like gdb
or IDE-integrated debuggers.
10. Conclusion
Congratulations! You’ve successfully built a basic web application using Rust, Actix, and Diesel. This tutorial covered setting up the environment, creating a project, defining routes and handlers, setting up a database, and connecting everything together.
Rust is a powerful language with a growing ecosystem for web development. By exploring more advanced topics and libraries, you can build even more robust and performant applications.
Feel free to expand on this tutorial, integrate more complex features, or explore other Rust web frameworks and libraries. Happy coding!