From 1d67dab0369968eddfdecfec5a0e03dc701bf7de Mon Sep 17 00:00:00 2001 From: chodak166 Date: Fri, 16 Jan 2026 17:36:02 +0100 Subject: [PATCH] WIP: basic API --- apps/app_api/src/api.rs | 9 ++++ apps/app_api/src/api/health.rs | 74 ++++++++++++++++++++++++++ apps/app_api/src/main.rs | 2 + apps/app_api/src/router.rs | 16 ++---- apps/app_api/src/router/handlers.rs | 25 --------- apps/app_api/src/router/responses.rs | 34 ------------ apps/app_api/src/{router => }/state.rs | 0 7 files changed, 89 insertions(+), 71 deletions(-) create mode 100644 apps/app_api/src/api.rs create mode 100644 apps/app_api/src/api/health.rs delete mode 100644 apps/app_api/src/router/handlers.rs delete mode 100644 apps/app_api/src/router/responses.rs rename apps/app_api/src/{router => }/state.rs (100%) diff --git a/apps/app_api/src/api.rs b/apps/app_api/src/api.rs new file mode 100644 index 0000000..4d016fd --- /dev/null +++ b/apps/app_api/src/api.rs @@ -0,0 +1,9 @@ +use crate::state::AppState; +use axum::Router; +use std::sync::Arc; + +pub mod health; + +pub fn routes() -> Router> { + Router::new().nest("/api", health::routes()) +} diff --git a/apps/app_api/src/api/health.rs b/apps/app_api/src/api/health.rs new file mode 100644 index 0000000..d4b9bc1 --- /dev/null +++ b/apps/app_api/src/api/health.rs @@ -0,0 +1,74 @@ +use axum::{ + Json, Router, + extract::State, + http::StatusCode, + response::IntoResponse, + routing::{get, post}, +}; +use chrono::Utc; +use serde::Serialize; +use serde_json::Value; +use std::sync::Arc; + +use crate::state::AppState; + +// --- DTOs --- + +#[derive(Debug, Serialize)] +pub struct EchoResponse { + pub data: Value, + pub timestamp: String, +} + +#[derive(Debug, Serialize)] +pub struct VersionResponse { + pub name: String, + pub version: String, +} + +#[derive(Debug, Serialize)] +pub struct ErrorResponse { + pub error: String, +} + +impl IntoResponse for ErrorResponse { + fn into_response(self) -> axum::response::Response { + (StatusCode::INTERNAL_SERVER_ERROR, Json(self)).into_response() + } +} + +impl From for ErrorResponse { + fn from(err: E) -> Self { + Self { + error: err.to_string(), + } + } +} + +// --- Handlers --- + +pub async fn echo_handler( + State(_state): State>, + Json(payload): Json, +) -> Result, ErrorResponse> { + let response = EchoResponse { + data: payload, + timestamp: Utc::now().to_rfc3339(), + }; + Ok(Json(response)) +} + +pub async fn version_handler(State(state): State>) -> Json { + Json(VersionResponse { + name: state.name.clone(), + version: state.version.clone(), + }) +} + +// --- Router --- + +pub fn routes() -> Router> { + Router::new() + .route("/echo", post(echo_handler)) + .route("/version", get(version_handler)) +} diff --git a/apps/app_api/src/main.rs b/apps/app_api/src/main.rs index 6ec4d00..56e87b8 100644 --- a/apps/app_api/src/main.rs +++ b/apps/app_api/src/main.rs @@ -1,8 +1,10 @@ +mod api; mod app; mod commands; mod config; mod container; mod router; +mod state; use anyhow::Result; use app::Application; diff --git a/apps/app_api/src/router.rs b/apps/app_api/src/router.rs index 16faf29..14b8078 100644 --- a/apps/app_api/src/router.rs +++ b/apps/app_api/src/router.rs @@ -1,22 +1,14 @@ -use axum::{ - Router, - routing::{get, post}, -}; +use axum::Router; use std::sync::Arc; use tower_http::{cors::CorsLayer, trace::TraceLayer}; -mod handlers; -mod responses; -mod state; - -pub use state::AppState; +use crate::api; +use crate::state::AppState; pub fn create_router() -> Router { let state = Arc::new(AppState::new()); - Router::new() - .route("/api/echo", post(handlers::echo_handler)) - .route("/api/version", get(handlers::version_handler)) + api::routes() .with_state(state) .layer(TraceLayer::new_for_http()) .layer(CorsLayer::permissive()) diff --git a/apps/app_api/src/router/handlers.rs b/apps/app_api/src/router/handlers.rs deleted file mode 100644 index ea79e21..0000000 --- a/apps/app_api/src/router/handlers.rs +++ /dev/null @@ -1,25 +0,0 @@ -use axum::{Json, extract::State}; -use chrono::Utc; -use serde_json::Value; -use std::sync::Arc; - -use super::responses::{EchoResponse, ErrorResponse, VersionResponse}; -use super::state::AppState; - -pub async fn echo_handler( - State(_state): State>, - Json(payload): Json, -) -> Result, ErrorResponse> { - let response = EchoResponse { - data: payload, - timestamp: Utc::now().to_rfc3339(), - }; - Ok(Json(response)) -} - -pub async fn version_handler(State(state): State>) -> Json { - Json(VersionResponse { - name: state.name.clone(), - version: state.version.clone(), - }) -} diff --git a/apps/app_api/src/router/responses.rs b/apps/app_api/src/router/responses.rs deleted file mode 100644 index e2ab6cd..0000000 --- a/apps/app_api/src/router/responses.rs +++ /dev/null @@ -1,34 +0,0 @@ -use axum::{Json, http::StatusCode, response::IntoResponse}; -use serde::Serialize; -use serde_json::Value; - -#[derive(Debug, Serialize)] -pub struct EchoResponse { - pub data: Value, - pub timestamp: String, -} - -#[derive(Debug, Serialize)] -pub struct VersionResponse { - pub name: String, - pub version: String, -} - -#[derive(Debug, Serialize)] -pub struct ErrorResponse { - pub error: String, -} - -impl IntoResponse for ErrorResponse { - fn into_response(self) -> axum::response::Response { - (StatusCode::INTERNAL_SERVER_ERROR, Json(self)).into_response() - } -} - -impl From for ErrorResponse { - fn from(err: E) -> Self { - Self { - error: err.to_string(), - } - } -} diff --git a/apps/app_api/src/router/state.rs b/apps/app_api/src/state.rs similarity index 100% rename from apps/app_api/src/router/state.rs rename to apps/app_api/src/state.rs