Today I Learned: Web Server with Rama

C…
crusty.rustacean
Published on November 11, 2025 • Updated November 13, 2025

A quick introduction to building a web server with the Rama modular framework.

notes
rust web-server networking http
0 likes

I’m all about learning the things that are not mainstream. Arguably, this is not the greatest approach, for the simple reason that I give myself too much to learn. Regardless, I’m enamoured of the notion of focusing on non-standard things, because it’s more interesting somehow than doing the same thing that a million other people are doing.

It’s unlikely I can contribute anything new, but hey, you never know.

Up next on my list is the Rama modular service framework.

Today, I set about to start a project where, over time, I’ll build out a web server with Rama and document the process. Leveraging a couple of the examples, here is what I consider a “Hello, World!” web server. It has exactly one route, at /health_check, which returns a 200 OK response with an empty body.

// src/main.rs

// dependencies
use rama::{
    http::service::web::Router,
    http::service::web::response::IntoResponse,
    http::{StatusCode, server::HttpServer},
    rt::Executor,
};

// health_check endpoint which returns a 200 OK response and empty body
async fn health_check() -> impl IntoResponse {
    StatusCode::OK
}

#[tokio::main]
async fn main() {
    let exec = Executor::default();
    let router = Router::new().get("/health_check", health_check);
    HttpServer::auto(exec)
        .listen("127.0.0.1:8080", router)
        .await
        .expect("Unable to start the server at 127.0.0.1:8080");
}

This is very basic and bare bones, not particularly useful, but it’s instructive as a starting point. Rama is by nature an async framework, built on the tokio crate. So we have to annotate our main function accordingly. So what’s going on after that?

Rama provides a convenient model of a server that listens for HTTP connections on a host and port, a struct type called HttpServer. This model has several methods we can use to “build” a server. Here’s what’s happening:

  • we need an executor which will handle the async details for us, we create a default one and bind it to a variable.
  • we need a router on which to route incoming requests in order to produce the desired response.
  • we leverage the Router type (which implements Rama’s core Service trait) to create a route that accepts GET requests to our handler health_check function
  • we start up our model server, which has an auto method that we pass our executor to, we then use the .listen() method which is a function that takes an address and our router, to start listening
  • we await to drive our future to completion
  • this whole business could fail, so at the moment, rather than crash out and panic, we try to at least have a helpful message with .expect().

When you compile and run this, then you can do:

curl -v https://localhost:8080/health_check

You should see an “200 OK” with content-length 0 indicating the empty response body.

Rama is in it’s early days, but offers a nice model for composing a web server. I’m glossing a lot of things over here in this simple example.

Stay tuned for more explorations!

The full repo for the project is here: hello-rama-web

C…
crusty.rustacean

Comments

Loading comments...