1mod graphql;
4mod gsp;
5mod mcp;
6mod openai;
7mod openai_v1;
8mod prometheus;
9mod sparql;
10mod well_known;
11
12#[cfg(feature = "app")]
13mod app;
14
15use axum::{Router, response::Json, routing::get};
16use tokio::net::{TcpListener, ToSocketAddrs};
17use tokio_util::sync::CancellationToken;
18use tower_http::cors::CorsLayer;
19
20pub fn routes() -> Router {
21 let router = Router::new()
22 .merge(graphql::routes())
23 .merge(gsp::routes())
24 .merge(mcp::routes())
25 .merge(openai::routes())
26 .merge(prometheus::routes())
27 .merge(sparql::routes())
28 .merge(well_known::routes());
29
30 #[cfg(feature = "app")]
31 let router = router.merge(app::routes());
32
33 #[cfg(feature = "tracing")]
34 let router = router.layer(
35 tower_http::trace::TraceLayer::new_for_http()
36 .make_span_with(tower_http::trace::DefaultMakeSpan::new().include_headers(true))
37 .on_request(
38 |request: &http::Request<axum::body::Body>, _span: &tracing::Span| {
39 tracing::info!(
40 "Received a {} {} request",
41 request.method(),
42 request.uri().path()
43 );
44 },
45 ),
46 );
47
48 router
49 .layer(CorsLayer::permissive())
50 .route("/", get(http_handler))
51}
52
53pub async fn start(addr: impl ToSocketAddrs, cancel: CancellationToken) -> std::io::Result<()> {
54 let listener = TcpListener::bind(addr).await?;
55
56 #[cfg(feature = "tracing")]
57 tracing::info!(
58 "Listening for HTTP requests on {}...",
59 listener.local_addr().unwrap()
60 );
61
62 axum::serve(listener, routes())
63 .with_graceful_shutdown(cancel.cancelled_owned())
64 .await
65}
66
67async fn http_handler() -> Json<&'static str> {
68 Json("Hello, world!") }