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.into
make_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) -> 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) -> &’static str {
state.count += 1;
“Hello, World!”
}

[tokio::main]

async fn main() {
let sharedstate = SharedState { count: 0 };
let app = Router::new()
.route(“/”, get(handler))
.layer(Extension(shared
state));
// …
}
“`
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.

Leave a Reply

Your email address will not be published. Required fields are marked *