Setup for axum serving static files and a rest API, using axum * took me a while to get right, but now it's no use anymore * assumes static files in ./assets * handles the mimetypes * the api may seem weird: it accepts a path param called `rgb_hex` and serves an image that is closest to that color (that code not here) ```rust use axum::body::Body; use axum::extract::Path; use axum::http::{header, Request, StatusCode, Uri}; use axum::response::{IntoResponse, Response}; use axum::{routing::get, Router}; use spiegel_server::{get_closest_color, init}; use tower::ServiceExt; use tower_http::services::ServeDir; #[tokio::main] async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); init(); let app = Router::new() .route("/color/:rgb_hex", get(fetch_nearest_color)) .nest_service("/", get(get_static_file)); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap(); Ok(()) } async fn get_static_file(uri: Uri) -> Result, (StatusCode, String)> { let req = Request::builder().uri(&uri).body(Body::empty()).unwrap(); match ServeDir::new("assets").oneshot(req).await { Ok(res) => Ok(res.map(Body::new)), Err(err) => Err(( StatusCode::INTERNAL_SERVER_ERROR, format!("Something went wrong: {}", err), )), } } async fn fetch_nearest_color( Path(rgb_hex): Path, ) -> Result { if rgb_hex.len() != 6 { return Err(( StatusCode::BAD_REQUEST, "input should be color hex, eg AA11CC".into(), )); } let closest = get_closest_color(&rgb_hex); let headers = [(header::CONTENT_TYPE, "image/jpeg")]; Ok((headers, closest.image)) } ```