Building a Simple Web Server in Rust Using Actix-web

  • 2024/7/29
  • Building a Simple Web Server in Rust Using Actix-web はコメントを受け付けていません

Introduction

Rust has been making waves in the programming world for its focus on safety, speed, and concurrency. There is a reason why it has been the most loved programming language 8 years in a row on StackOverflow.

 It’s a language designed to improve upon some of the shortcomings of C and C++ while providing modern features. One area where Rust is gaining traction is web development, and one of the prominent frameworks in this space is Actix-web. In this blog, we’ll explore how to build a simple web server using Rust and Actix-web, complete with user data handling. 

We will be building a very simple web server with two routes as exemplar:
1. / : an entrypoint into every programming language has been used as the base example of a get route which will respond with a “Hello world!”
2.  /users/{user_id} : A simple get route which fetches users from a constant list defined as a constant

Why Rust?

Rust was chosen for several reasons:

  1. Safety: Rust’s strict compile-time checks help prevent common bugs and security vulnerabilities such as null pointer dereferencing and buffer overflows.
  2. Performance: Rust’s performance is on par with C and C++ due to its lack of runtime overhead.
  3. Concurrency: Rust’s ownership model naturally prevents data races, making it easier to write concurrent programs.

Why Actix-web?

Actix-web is a powerful, pragmatic, and extremely fast web framework for Rust. Here’s why Actix-web is a great choice:

  1. Performance: Actix-web is known for its high performance and has been benchmarked as one of the fastest web frameworks.
  2. Asynchronous: Built on top of the Actix actor framework, it supports asynchronous request handling out of the box.
  3. Feature-rich: Actix-web comes with a plethora of features like routing, middleware, and built-in support for common tasks like JSON handling.

The Code

Below is a step-by-step walkthrough of a simple web server implemented in Rust using Actix-web.

Step 1: Setting Up the Project

First, create a new Rust project using Cargo:

cargo new rust_actix_web_server

cd rust_actix_web_server

Add actix-web and serde to your Cargo.toml:

[dependencies]

actix-web = "4"

serde = { version = "1.0", features = ["derive"] }

serde_json = "1.0"

Step 2: Define the User Struct

We start by defining a simple User struct:

use serde::Serialize;

 

#[derive(Serialize)]

struct User {

    user_id: u32,

    name: &'static str,

}

 

static USERS: [User; 2] = [

    User { user_id: 0, name: "John Doe" },

    User { user_id: 1, name: "Jane Doe" },

];

 

Here, we use serde for serializing our User struct into JSON. We also create a static array of User instances.

Step 3: Creating Route Handlers

Next, we define our route handlers. The hello_world handler responds to the root URL (/) with a simple “Hello world!” message:

use actix_web::{get, HttpResponse, Responder};

 

#[get("/")]

async fn hello_world() -> impl Responder {

    HttpResponse::Ok().body("Hello world!")

}

 

The get_user handler fetches a user by their user_id:

use actix_web::{web, get};

 

#[get("/users/{user_id}")]

async fn get_user(user_id: web::Path<u32>) -> impl Responder {

    let user = USERS.iter().find(|user| user.user_id == *user_id);

    

    match user {

        Some(user) => {

            let body = serde_json::to_string(user).unwrap();

            HttpResponse::Ok()

                .content_type("application/json")

                .body(body)

        },

        None => HttpResponse::NotFound().body("User not found"),

    }

}

 

Here, we extract the user_id from the URL, search for the user in our static array, and respond with the user’s data in JSON format if found, or a “User not found” message otherwise.

Step 4: Configuring the Server

Finally, we configure our server in the main function:

use actix_web::{App, HttpServer};

 

#[actix_web::main]

async fn main() -> std::io::Result<()> {

    HttpServer::new(|| {

        App::new()

            .service(hello_world)

            .service(get_user)

    })

    .bind(("127.0.0.1", 8080))?

    .run()

    .await

}

 

In the main function, we create an HttpServer, configure it with our route handlers using App::new, and bind it to 127.0.0.1:8080.

Running the Server

To run the server, use the following command:

cargo run

Open your browser and navigate to http://127.0.0.1:8080 to see the “Hello world!” message. For user data, navigate to http://127.0.0.1:8080/users/0 or http://127.0.0.1:8080/users/1.

Conclusion

In this blog, we’ve built a simple web server using Rust and Actix-web. We covered why Rust and Actix-web are excellent choices for web development and walked through the implementation of a basic server that serves static user data. This example demonstrates the powerful combination of Rust’s safety and performance with Actix-web’s high-speed, asynchronous capabilities. Whether you’re a seasoned Rustacean or new to the language, Actix-web offers a robust framework for building web applications.

関連記事

カテゴリー:

ブログ

情シス求人

  1. チームメンバーで作字やってみた#1

ページ上部へ戻る