mod convert;
mod error;
mod handlers;
mod json;
use std::sync::Arc;
use axum::extract::DefaultBodyLimit;
use axum::routing::{get, post, put};
use axum::serve::ListenerExt;
use axum::Router;
use crate::core::MurrError;
use crate::service::MurrService;
pub struct MurrHttpService {
service: Arc<MurrService>,
}
impl MurrHttpService {
pub fn new(service: Arc<MurrService>) -> Self {
Self { service }
}
pub fn router(&self) -> Router {
Router::new()
.route("/openapi.json", get(handlers::openapi))
.route("/health", get(handlers::health))
.route("/api/v1/table", get(handlers::list_tables))
.route("/api/v1/table/{name}/schema", get(handlers::get_schema))
.route("/api/v1/table/{name}", put(handlers::create_table))
.route("/api/v1/table/{name}/fetch", post(handlers::fetch))
.route("/api/v1/table/{name}/write", put(handlers::write_table))
.layer(DefaultBodyLimit::max(
self.service.config().server.http.max_payload_size,
))
.with_state(self.service.clone())
}
pub async fn serve(self) -> Result<(), MurrError> {
let addr = self.service.config().server.http.addr();
let listener = tokio::net::TcpListener::bind(&addr)
.await
.map_err(|e| MurrError::IoError(format!("binding to {addr}: {e}")))?
.tap_io(|stream| { stream.set_nodelay(true).ok(); });
axum::serve(listener, self.router())
.await
.map_err(|e| MurrError::IoError(format!("serving: {e}")))?;
Ok(())
}
}