Building a Scalable Rust Web Server with Axum and Deploying to Heroku
Are you interested in building a scalable and performant web server using Rust? Look no further than Axum, a thin layer over Hyper that provides a flexible and extensible framework for building web services. In this article, we’ll explore how to build a simple web server using Axum and deploy it to Heroku using GitHub Actions.
Setting up a Simple Server with Axum
Axum provides a user-friendly interface for mounting routes on a server and passing handler functions. The Router
struct provides a route
method to add new routes and respective handlers. For example, we can create a simple “Hello World” handler using the get
function:
“`rust
use axum::{
routing::get,
Router,
};
async fn hello_world() -> &’static str {
“Hello, World!”
}
[tokio::main]
async fn main() {
let app = Router::new().route(“/”, get(helloworld));
axum::Server::bind(&”0.0.0.0:8080″.parse().unwrap())
.serve(app.intomake_service())
.await
.unwrap();
}
“`
Handling POST Requests
In addition to handling GET requests, Axum also provides support for handling POST requests using the post
function. We can use the Json
type to serialize and deserialize JSON data:
“`rust
use axum::{
extract::Json,
routing::post,
Router,
};
struct Request {
name: String,
}
struct Response {
message: String,
}
async fn handle_post(Json(request): Json
let response = Response {
message: format!(“Hello, {}!”, request.name),
};
Json(response)
}
[tokio::main]
async fn main() {
let app = Router::new().route(“/post”, post(handle_post));
// …
}
“`
Using Extractors to Share State
Axum provides extractors as an abstraction to share state across your server and allows access to shared data to handlers. We can use the Extension
type to wrap shared state and interact with Axum:
“`rust
use axum::{
extract::Extension,
routing::get,
Router,
};
struct SharedState {
count: u32,
}
async fn handler(Extension(state): Extension
state.count += 1;
“Hello, World!”
}
[tokio::main]
async fn main() {
let sharedstate = SharedState { count: 0 };
let app = Router::new()
.route(“/”, get(handler))
.layer(Extension(sharedstate));
// …
}
“`
Deploying to Heroku using GitHub Actions
To deploy our Axum app to Heroku, we can use GitHub Actions to automate the process. We’ll create a workflow that builds our app, creates a Heroku app, and deploys our app to Heroku:
“`yml
name: Deploy to Heroku
on:
push:
branches:
– main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
– name: Checkout code
uses: actions/checkout@v2
– name: Build and deploy
env:
HEROKUAPIKEY: ${{ secrets.HEROKUAPIKEY }}
HEROKUAPPNAME: my-axum-app
run: |
cargo build –release
heroku create ${HEROKUAPPNAME}
heroku git:remote -a ${HEROKUAPPNAME}
git push heroku main
“`
That’s it! With these steps, you can build a scalable and performant web server using Axum and deploy it to Heroku using GitHub Actions.