Rust: Create a basic web/HTTP server

Mar 25, 2022

For the web server we're going to use the same HTTP library we used for making requests, Hyper. The Hyper docs actually have a really great guide for creating a server which is exactly what this has been based off. Here's my version:

use hyper::{Body, Request, Response, Server, Method, StatusCode};
use hyper::service::{make_service_fn, service_fn};

async fn echo(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
    match (req.method(), req.uri().path()) {
        // Serve some instructions at /
        (&Method::GET, "/") => Ok(Response::new(Body::from(
            "Welcome! Try a GET to /hello",
        ))),

        (&Method::GET, "/hello") => Ok(Response::new(Body::from(
            "World!",
        ))),

        // Simply echo the body back to the client.
        (&Method::POST, "/echo") => Ok(Response::new(req.into_body())),

        // Return the 404 Not Found for other routes.
        _ => {
            let mut not_found = Response::default();
            *not_found.status_mut() = StatusCode::NOT_FOUND;
            Ok(not_found)
        }
    }
}

async fn shutdown_signal() {
    // Wait for the CTRL+C signal
    tokio::signal::ctrl_c()
        .await
        .expect("failed to install CTRL+C signal handler");
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let addr = ([127, 0, 0, 1], 3000).into();

    let service = make_service_fn(|_| async { Ok::<_, hyper::Error>(service_fn(echo)) });

    let server = Server::bind(&addr).serve(service);

    println!("Listening on http://{}", addr);

    let graceful = server.with_graceful_shutdown(shutdown_signal());

    // Run this server for... forever!
    if let Err(e) = graceful.await {
        eprintln!("server error: {}", e);
    }

    Ok(())
}
Hi, I'm Glenn! 👋 I'm currently Director of Product (Terraform) @ HashiCorp, and we're hiring! If you'd like to come and work with me and help make Terraform Cloud even more amazing we have multiple positions opening in Product ManagementDesign, and Engineering & Engineering Management across a range of levels (i.e., junior through to senior). Please send in an application ASAP so we can get in touch.