api-server/src/main.rs

76 lines
1.9 KiB
Rust
Raw Normal View History

mod dem;
use axum::{
extract::{Path, State},
http::StatusCode,
response::IntoResponse,
routing::get,
Router,
};
use axum_macros::debug_handler;
use std::env;
use tower_http::{
services::ServeDir,
trace::{self, DefaultMakeSpan},
};
use dem::DatasetRepository;
use tower_http::trace::TraceLayer;
use tracing::{info, Level, Span};
const DEFAULT_DATA_DIR: &str = "/data";
const DEFAULT_PORT: &str = "3000";
#[tokio::main]
async fn main() {
// initialize tracing
tracing_subscriber::fmt::init();
let config = load_config().unwrap();
let cache = DatasetRepository::new(config.basedir);
let serve_dir = ServeDir::new("assets");
let app = Router::new()
.route("/elevation/:lat/:lon", get(get_elevation))
.nest_service("/", serve_dir)
.with_state(cache)
.layer(
TraceLayer::new_for_http()
.make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO))
.on_response(trace::DefaultOnResponse::new().level(Level::INFO)),
);
let host = format!("[::]:{}", config.port);
info!("Will start server on {host}");
let listener = tokio::net::TcpListener::bind(host).await.unwrap();
axum::serve(listener, app).await.unwrap();
}
#[debug_handler]
async fn get_elevation(
State(dsr): State<DatasetRepository>,
Path((lat, lon)): Path<(f64, f64)>,
) -> impl IntoResponse {
let ele = dem::elevation_from_coordinates(dsr, lat, lon);
match ele.await {
Some(ele) => (StatusCode::OK, format!("{ele}")),
None => (StatusCode::NOT_IMPLEMENTED, "".to_string()),
}
}
fn load_config() -> Result<Config, env::VarError> {
Ok(Config {
basedir: env::var("DEM_LOCATION").unwrap_or_else(|_| DEFAULT_DATA_DIR.to_string()),
port: env::var("HTTP_PORT").unwrap_or_else(|_| DEFAULT_PORT.to_string()),
})
}
struct Config {
basedir: String,
port: String,
}