1pub mod bus;
2pub mod config;
3pub mod handlers;
4pub mod hub;
5pub mod local_bus;
6pub mod metrics;
7pub mod mqtt;
8pub mod nats_bus;
9pub mod presence;
10pub mod ws;
11
12use axum::{
13 http::StatusCode,
14 response::{IntoResponse, Response},
15 routing::{delete, get, post, put},
16 Json, Router,
17};
18use freshblu_core::error::FreshBluError;
19use freshblu_store::DynStore;
20use serde_json::json;
21use tower_http::{cors::CorsLayer, trace::TraceLayer};
22
23pub use bus::DynBus;
24pub use config::ServerConfig;
25pub use hub::MessageHub;
26
27pub struct ApiError(pub FreshBluError);
29
30impl From<FreshBluError> for ApiError {
31 fn from(e: FreshBluError) -> Self {
32 ApiError(e)
33 }
34}
35
36impl IntoResponse for ApiError {
37 fn into_response(self) -> Response {
38 let status = StatusCode::from_u16(self.0.http_status())
39 .unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
40 let body = json!({ "error": self.0.to_string() });
41 (status, Json(body)).into_response()
42 }
43}
44
45#[derive(Clone)]
47pub struct AppState {
48 pub store: DynStore,
49 pub bus: DynBus,
50 pub config: ServerConfig,
51}
52
53pub fn build_router(state: AppState) -> Router {
54 let app = Router::new()
55 .route("/status", get(handlers::status::status))
57 .route("/authenticate", post(handlers::auth::authenticate))
59 .route("/devices", post(handlers::devices::register))
61 .route("/devices/search", post(handlers::devices::search))
62 .route("/devices/:uuid", get(handlers::devices::get_device))
63 .route("/devices/:uuid", put(handlers::devices::update_device))
64 .route("/devices/:uuid", delete(handlers::devices::unregister))
65 .route("/v2/devices", post(handlers::devices::register))
67 .route("/v2/devices/:uuid", get(handlers::devices::get_device))
68 .route("/v2/devices/:uuid", put(handlers::devices::update_device))
69 .route("/v2/devices/:uuid", delete(handlers::devices::unregister))
70 .route("/v2/devices/search", post(handlers::devices::search))
71 .route("/v3/devices/:uuid", get(handlers::devices::get_device))
73 .route("/whoami", get(handlers::devices::whoami))
75 .route("/v2/whoami", get(handlers::devices::whoami))
76 .route("/messages", post(handlers::messages::send_message))
78 .route("/v2/messages", post(handlers::messages::send_message))
79 .route("/mydevices", get(handlers::devices::my_devices))
81 .route(
83 "/devices/:uuid/subscriptions",
84 post(handlers::subscriptions::create_subscription),
85 )
86 .route(
87 "/devices/:uuid/subscriptions",
88 get(handlers::subscriptions::list_subscriptions),
89 )
90 .route(
91 "/devices/:uuid/subscriptions/:emitter_uuid/:sub_type",
92 delete(handlers::subscriptions::delete_subscription),
93 )
94 .route(
96 "/devices/:uuid/tokens",
97 post(handlers::tokens::generate_token),
98 )
99 .route(
100 "/devices/:uuid/tokens/:token",
101 delete(handlers::tokens::revoke_token),
102 )
103 .route("/ws", get(ws::ws_handler))
105 .route("/socket.io", get(ws::ws_handler))
106 .route("/metrics", get(metrics::metrics_handler))
108 .layer(CorsLayer::permissive())
110 .layer(TraceLayer::new_for_http())
111 .with_state(state);
112
113 app
114}