Actix Web is a high-performance Rust microframework for crafting robust and efficient web applications, APIs, and web services. In this guide, you’ll learn all you need to know if you are considering adopting the Actix Web framework in your organization or team.
Let’s dive in to help you make a more informed decision.
What is Actix Web?
Based on the first release date listed in GitHub, Actix Web was started in 2017 by Nikolay Kim, a Principal Software Engineer at Microsoft, as an open source project. He was inspired by the actor model and built Actix Web on top of the Rust Actix framework, an Actor framework for Rust.
Actix Web leverages the Actor model’s principles for handling concurrent tasks, making it highly scalable and efficient. While it has since moved away from the Actor framework, it still maintains its high performance and is one of few Rust web frameworks that runs on stable Rust.
Actix Web began when there were not so many mature Rust frameworks — just Rocket and a handful of other upcoming Rust web frameworks.
In a benchmark performed by TechEmpower, Rust Actix Web performed way better than the other 360 web frameworks that were tested, including prominent ones like Rocket:
Actix Web has been in active development and has even crossed the v1.0 mark. It’s a testament to the dedication and commitment of the Rust community to the project.
Further reading:
- How to create a web app in Rust with Rocket and Diesel
- Building a REST API in Rust with Rhai and Actix Web
Why use Actix Web?
Choosing Actix Web allows you to enjoy all the benefits of Rust like static typing, memory safety, and more. However, there are even more benefits that Actix Web as a framework brings to the table, setting it apart from other web frameworks.
Let’s discuss a few of those situations you might want to consider using Actix Web.
Performance: Highly concurrent applications
From the start of Actix Web, one of the key feature was to build a web framework that allows for efficient concurrency to allow developers build extremely fast and scalable web applications. It’s safe to say that it has maintained that standard.
When the original author was asked why Actix is so fast, he gave the following reasons in a post on GitHub:
You’ll notice that even though Actix Web is single-threaded, it leverages multiple independent threads to handle concurrent requests, as every task runs on its own thread. Furthermore, there’s been so much intentional effort invested in the project to ensure that it’s extremely fast and efficient.
So, if you are looking to build software that prioritizes concurrency, Actix Web could be a good choice.
Modularity
Actix Web has lots of features. However, you might not need all of them. It leverages a modular design to allow you use only what you need. You’ll see this firsthand through the way its middleware system, core modules, and custom modules are designed.
Community and ecosystem
Actix Web has one of the largest Rust developer community. It enjoys over 19k GitHub stars, 16 million+ downloads, several books and courses, and more than 500 Stack Overflow questions.
With all of these resources, it’s very easy to find help around the community if you get stuck. The Actix Web community has also had its own share of challenges. For example, at one time, the author left the project — however, Yuki Okushi was later assigned as the project leader.
Developer experience and ease of use
Actix Web doesn’t have a very steep learning curve if you’re already familiar with Rust. It’s easy to pick up and run with it.
However, one concern I had while trying to use Actix Web earlier on was the middleware system design. While it gives you a lot of control and low-level API access, it uses a lot of generics and traits. It can seem verbose for someone new to Rust compared to the middleware design of warp and Axum.
Further reading:
Bundle size
With about 32 dependencies, the Actix Web crate has a bundle size around 226 kB. I think that’s a decent bundle size for a powerful framework like Actix Web. The Rocket framework has a bundle size a little larger than Actix Web — around 284 kB.
Here is a bundle size comparison table for some of the popular Rust web frameworks:
Framework | Bundle size (KiB) |
---|---|
Rocket | 284 |
Warp | 114 |
Axum | 148 |
Actix Web | 226 |
While the base dependencies are lightweight, the eventual size of your Actix Web project will depend on your code and the dependencies you’ll add to your project.
Further reading:
Documentation
The Actix Web documentation is pretty good and thorough. It’s arranged in a way that it’s easy to navigate for new users of the framework, as well as for more advanced users:
Plus, it has lots of code examples to show you how a feature works in every section of the documentation. Interestingly, it also includes diagrams that show the working principles of the Actix Web server and the connection life cycle.
Integrations
Actix Web integrates seamlessly with other Rust libraries and ecosystem of tools. You can also create extension methods or leverage the Actix Web middleware system to extend the functionality of the framework.
Getting started with Actix Web
To quickly set up an Actix Web project, you’ll need to make sure you have Rust installed. If you don’t have Rust installed, just run the code below to install Rust and its development tools with Rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Once you have Rust installed, you’ll be able to use Cargo, Rust’s build tool and package manager. Use it to generate a new Rust project by running the command below:
cargo new my-web-app
A folder with the following structure will be generated for you;
. ├── Cargo.toml └── src └── main.rs
Navigate into the directory with cd my-web-app
and run cargo add actix-web
:
Your Cargo.toml
file should look like this by now, if you are following along:
[package] name = "my-web-app" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] actix-web = "4.5.1"
You are all set to start building on Actix Web. You can start by writing your first Hello World
web server and endpoint with the code below:
use actix_web::{get, web, App, HttpServer, Responder}; #[get("/hello/{first_name}")] async fn hello(first_name: web::Path<String>) -> impl Responder { format!("Hello World, {first_name}") } #[actix_web::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new().service(hello) }) .bind(("127.0.0.1", 3000))? .run() .await }
Key Actix Web features to know
Actix Web has a lot of features, which you can learn from the documentation. For the purposes of this guide, we’ll go over three features that stand out for me: the routing system, handlers, and extractors.
Routing in Actix Web
The routing system in Actix Web resembles that of popular frameworks like NestJS in JavaScript, Flask in Python, and Sinatra in Ruby. This helps reduce the entrance barrier, as this routing system design is quite popular. The example below shows a simple get
route:
#[get("/")] async fn index() -> impl Responder { "Hello, World!" }
See how the route is defined on top of the handler function as an attribute? That’s very intuitive and easy to maintain.
Further reading:
- Take your Node backend to the next level with NestJS
- Build and deploy a Flask app using Docker
- 11 alternative frameworks to Ruby on Rails
Handlers
Handlers are asynchronous functions responsible for processing incoming web requests. They accept extractors as parameters to extract information from the request, perform the necessary logic, and return a response.
In Actix Web, handlers go hand-in-hand with the routing. Think of it like your controller and service function combined, with the route as an attribute. That goes a long way to reduce the complexity of your project — you can review the entire functionality that matches that route holistically and easily.
The example below shows how you can extract a product id from from a path parameter:
#[get("/{id}")] async fn product(id: web::Path<String>) -> impl Responder { format!("Your Id {}!", &id) }
The route and handler expect the request to be in this format:
https://localhost:8080/random-id
As a GET request, we can also get the request body using a JSON format. This is made possible by the extractor:
The handlers also allows you to specify the return type. As long as your return type implements impl Responder
, you can use it directly in your handler function.
For example, the &'static str
and String
types implements the Responder
trait by default. You can check the documentation to find more default Responders
. But if you want a custom Response, you can also, implement the trait for your specific use case.
Extractors
We’ve already seen extractors in action in the previous section. Extractors allows you to get information from an incoming request.
You can use up to 12 extractors per handler function in Actix Web. In other words, you have the chance to use up to 12 extractors to get information from a request in various ways. With the many extractors that Actix Web provide, you can extract information from:
- Path parameter
- Query parameters
- JSON request body
And more. You can also convert the payload of a request to a String
or Bytes
. Learn more about extractors in the documentation.
Use cases for Actix Web
Actix Web has a handful of use cases that suit a wide range of needs. While it’s not a frontend framework, it integrates nicely with frontend frameworks like HTMX and templating engines like Askama. Therefore, you can use it to build full-scale web-based infrastructures, from Web APIs and microservices to full-stack web applications.
Since Actix Web is a server-side framework and does not have a reactive frontend, if you are looking to build a reactive frontend, you can either sprinkle in some HTMX or use a framework like SolidJS, Leptos, or Dioxus as the frontend that talks to your Actix Web API.
Further reading:
- Build a real-time chat app with Rust Actix Web and React
- How to create a backend API with Rust and Postgres
- Introduction to SolidJS
- Using Dioxus with Rust to build performant single-page apps
- Using Rust and Leptos to build beautiful, declarative UIs
Deploying your Actix Web project
Deploying your Actix Web application is like deploying any Rust application. You’ll create a production build by running the following command:
cargo build --release
When the build is complete, you’ll get a production release in the target/release
directory, which you can deploy to any server by running the executable:
As shown in the screenshot above, you should run the web-app
and web-app.d
files to start the server, but you should deploy the entire release
directory. While the web-app
is the normal executable, the web-app.d
is a daemon and might require appropriate permission to run it on your server.
The web-app
name is the name of your project as specified in the Cargo.toml
file:
You can choose to run your deployment however you wish as long as your deployment runs the executable or daemon and has the required release files, as we’ve described. A few deployment tools that meet these requirements include Docker, Render, and Heroku.
Further reading:
Actix Web vs. similar
We’ve seen Rust web frameworks evolve both before and after Actix Web came about. Let’s see how Actix Web measures up against Rust web frameworks such as warp, Rocket, and Axum in the table below:
Aspect | Actix Web | warp | Rocket | Axum |
---|---|---|---|---|
Features | Standard features for modern web app framework, async/await, WebSockets | Lightweight, async/await, composable, lots of abstraction | Uses a lot of macros, async/await compatibility, security features like request guards | Prioritizes simplicity, expressiveness, modularity, and high-level abstraction |
Performance | Highly performant, efficient concurrency | Impressive performance, minimal resource overhead | Performant, potential slightly higher overhead | Good performance, prioritizes simplicity |
Community | One of the largest communities with over 19k+ GitHub stars and more than 19.8+ million downloads | Newer framework; growing and supportive community with 8.9k GitHub stars and more than 13 million downloads | One of the earliest Rust web frameworks still active; huge community with more than 22k GitHub stars | Enjoys a lot of support from the Rust ecosystem; growing community with over 14k GitHub stars and 248 contributors |
Documentation/Resources | The documentation is good enough to get you started and digging deep into the features. There are also lots and lots of community tutorials to help keep you going | Uses auto-generated Rust documentation; I am not really a fan of that documentation style but it works | Thorough and in-depth documentation, but goes out-of-date quickly | Similar to warp, uses auto-generated Rust documentation |
Use case | Use Actix when you are looking to build a complex system | Use warp for smaller projects, as it’s easier to reason about and has a less steep learning curve | While you can use Rocket for any kind of project from minimal to complex, it is better suited to more complex projects | Axum is powerful and can be used for both complex and simple projects. Its barrier to entry is not so high as long as you know some Rust |
As you can see, they mostly have similar features, although some still have some unique features. However, if you have a complex project that requires efficient concurrency and you’re looking to have complex lower-level access to core framework functionalities for customization, Actix Web is a great choice.
Ultimately, your choice will depend on your project’s complexity along with its general and specific requirements.
Conclusion
Actix Web is one of the most mature Rust web frameworks. It’s a powerful tool that’s been battle-tested by a lot of organizations. For the most part, Actix Web doesn’t have any significant drawbacks except for the middleware system design mentioned earlier.
Whether you are starting a new project or considering a framework switch, Actix Web is definitely a compelling option to consider. It enjoys continued community support, and there are a lot tutorials and materials to help you get started.
The post Actix Web adoption guide: Overview, examples, and alternatives appeared first on LogRocket Blog.