In 2023, which Rust web framework will be the best for looking into before you start developing APIs and web applications? Here, we’ll look at some of the most popular frameworks currently in use or looks promising. We’ll also explore look at some simple examples to look at their design principles
A web framework (WF) or web application framework (WAF) is a software framework that is designed to support the development of web applications including web services, web resources, micro-services, and web APIs. Web frameworks provide a standard way to build and deploy web applications on the World Wide Web. Web frameworks aim to automate the overhead associated with common activities performed in web development.
For example, many web frameworks provide libraries for database access, templating frameworks (HTML, JSON etc), and session management, and they often promote code reuse. Although they often target development of dynamic web sites, they are also applicable to static websites.
Rust is a programming language that offers great potential for web development. It is fast, safe, and provides many perfect features for building web applications. Here are some of the best framework and their features to consider for development
Table of Contents
- Hyper - Fast and safe HTTP
- Actix Web - Powerful, Pragmatic and Fast
- Rocket - Write fast and Secure
- Tide - Minimal and Pragmatic
- Warp - Super-Easy and Composable
- Axum - Focus on Ergonomics and Modularity
Hyper
Hyper is still being developed, it may have a stable release in 2023. But Hyper looks like a promising framework to explore into in 2023 before you decide to build a web application in Rust.
hyper is planning a stable 1.0 release at the end of January 2023. If you’d like to learn more about the move to stable 1.0, look out to here
hyper is a fast HTTP implementation written in and for Rust. Hyper is can be used as a:
- A Client for talking to web services.
- A Server for building those web services.
- Blazing fast (because of Rust)
- Have High concurrency with non-blocking sockets.
- Implements both HTTP/1 and HTTP/2 support.
use std::{convert::Infallible, net::SocketAddr, error::Error};
use http_body_util::Full;
use hyper::{Request, Response, body::Bytes, service::service_fn};
use hyper::server::conn::http1;
use tokio::net::TcpListener;
async fn hello(
_: Request<hyper::body::Incoming>,
) -> Result<Response<Full<Bytes>>, Infallible> {
Ok(Response::new(Full::new(Bytes::from("Hello World!"))))
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let listener = TcpListener::bind(addr).await?;
loop {
let (stream, _) = listener.accept().await?;
tokio::task::spawn(async move {
if let Err(err) = http1::Builder::new()
.serve_connection(stream, service_fn(hello))
.await
{
println!("Error serving connection: {:?}", err);
}
});
}
}
Any developer using a rust api framework needs to know about Hyper. It comes with a lot of features, and it is easy to use. The documentation is also top-notch, making it a great learning resource for new developers.
Actix-web
Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust. Actix Web is based on Rust Actor Model. It is highly performant web framework written in Rust with robust set of features for building a web application. Actix Web is Type Safe, Fearure Rich, Extensible and Blazingly Fast. Active Web supports
- Supports multiplexing
- Asynchronous I/O
- WebSockets
- Middleware support
Here is how to write a webpage that responds in ‘Hello World’:
use actix_web::{get, web, App, HttpRequest, HttpServer, Responder};
#[get("/")]
async fn index(_req: HttpRequest) -> impl Responder {
"Hello from the index page."
}
async fn hello(path: web::Path<String>) -> impl Responder {
format!("Hello World {}!", &path)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(index)
.route("/{name}", web::get().to(hello))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
To run server above use cargo run
and then open browser at http://localhost:8080/pankaj
. You should see Hello World pankaj!
Rocket
Rocket is a web framework for Rust that makes it simple to write fast web applications without sacrificing flexibility or type-safe, boilerplate free, extensible and easy-to-use.
Rocket believes in convention over configuration
philosophy and aims to get you up and running with minimal configuration. It integrates tightly with the Rust ecosystem, making it easy to use existing libraries and tools.
Following is an example of a page deployed at PUT /:id
url, which takes a JSON payload and stores into database. Here is an example of implementation of webpage:
#[derive(Serialize, Deserialize)]
struct Message<'r> {
contents: &'r str,
}
#[put("/<id>", data = "<msg>")]
fn update(db: &Db, id: Id, msg: Json<Message<'_>>) -> Value {
if db.contains_key(&id) {
db.insert(id, msg.contents);
json!({ "status": "ok" })
} else {
json!({ "status": "error" })
}
}
Rocket, supports Templating, Cookies, Async Streams out of the box. To dive deeper you can start with Rocket Guide
Tide
Tide is a minimal and pragmatic web application framework built on Rust. Tide is built for rapid web development. Tide comes with robust set of in-built features to make it easy building async web applications and APIs. Tide is based on rust actix web framework.
Tide is feature rich web framework. Tide is being developed actively and has wide community resources to get you up and running quickly
Tide framework has following features to help quickly build applications
- Async/await Support
- Type Safe Routing
- Request Guards
- Templating support
- Session Management
- Websockets Support
Let’s look at example of implementing endpoint with HTTP POST verb
use tide::Request;
use tide::prelude::*;
#[derive(Debug, Deserialize)]
struct Animal {
name: String,
legs: u16,
}
#[async_std::main]
async fn main() -> tide::Result<()> {
let mut app = tide::new();
app.at("/orders/shoes").post(order_shoes);
app.listen("127.0.0.1:8080").await?;
Ok(())
}
async fn order_shoes(mut req: Request<()>) -> tide::Result {
let Animal { name, legs } = req.body_json().await?;
Ok(format!("Hello, {}! I've put in an order for {} shoes", name, legs).into())
}
Now you can access /orders/shoes
endpoint with a JSON payload, using curl
curl localhost:8080/orders/shoes -d '{ "name": "Pankaj", "legs": 9 }'
This will respond with expected message Hello, Pankaj! I've put in an order for 9 shoes
Warp
Warp is super-easy, composable, web server framework built on Rust for warp speeds. The prominent or outstanding building block of Warp is Filter, which can be combined and composed to express rich requirements on requests
Thanks to its Filter system, warp provides these out of the box:
- Path routing and parameter extraction
- Header requirements and extraction
- Query string deserialization
- JSON and Form bodies
- Multipart form data
- Static Files and Directories
- Websockets
- Access logging
- Gzip, Deflate, and Brotli compression
- Server-Sent Events (SSE)
Since it builds on top of hyper and Tokio - An asynchronous Rust runtime, you automatically get:
- HTTP/1 and HTTP/2 Support
- Asynchronous feature
- One of the fastest HTTP implementations
- Tested and correct
Here’s a simple “Hello, world” example using Warp:
//main.rs
use warp::Filter;
#[tokio::main]
async fn main() {
// GET /hello/warp => 200 OK with body "Hello, warp!"
let hello = warp::path!("hello" / String)
.map(|name| format!("Hello, {}!", name));
warp::serve(hello)
.run(([127, 0, 0, 1], 3030))
.await;
}
Run it using cargo run main.rs
Axum
Axum web framework is built to be efficient, fast, and lightweight. Axum is inspired by The Erlang programming language, equipping developers with efficient concurrency and is perfect for developing real-time web applications, micro-services and low-latency systems. Axum is a web application framework that focuses on ergonomics and modularity.
To use Axum, you need Rust version v1.6 or greater
Axum’s features include:
- Route requests to handlers with a macro free API.
- Declaratively parse requests using extractors.
- Simple and predictable error handling model.
- Generate responses with minimal boilerplate.
- Take full advantage of the tower and tower-http ecosystem of middleware, services, and utilities.
- Support for WebSockets and other protocols
- Asynchronous I/O
use actix_web::{web, App, Responder};
fn index() -> impl Responder {
"Hello, world!"
}
fn main() {
App::new().route("/", web::get().to(index)).run();
}
Frameworks listed above are just some of the best web application framework to look out in year 2023. All of them have different design capabilities. Try and test them and use according to your requirements to implement a we application in year 2023.
Further reading material to study the language:
Online - The Rust Programming Language
NoStarch - The Rust Programming Language
Manning Publications - Rust Servers, Services, and Apps
About The Author
I am Pankaj Baagwan, a System Design Architect. A Computer Scientist by heart, process enthusiast, and open source author/contributor/writer. Advocates Karma. Love working with cutting edge, fascinating, open source technologies.
To consult Pankaj Bagwan on System Design, Cyber Security and Application Development, SEO and SMO, please reach out at me[at]bagwanpankaj[dot]com
For promotion/advertisement of your services and products on this blog, please reach out at me[at]bagwanpankaj[dot]com
Stay tuned <3. Signing off for RAAM