7 changed files with 89 additions and 71 deletions
@ -0,0 +1,9 @@ |
|||||||
|
use crate::state::AppState; |
||||||
|
use axum::Router; |
||||||
|
use std::sync::Arc; |
||||||
|
|
||||||
|
pub mod health; |
||||||
|
|
||||||
|
pub fn routes() -> Router<Arc<AppState>> { |
||||||
|
Router::new().nest("/api", health::routes()) |
||||||
|
} |
||||||
@ -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<E: std::error::Error> From<E> for ErrorResponse { |
||||||
|
fn from(err: E) -> Self { |
||||||
|
Self { |
||||||
|
error: err.to_string(), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// --- Handlers ---
|
||||||
|
|
||||||
|
pub async fn echo_handler( |
||||||
|
State(_state): State<Arc<AppState>>, |
||||||
|
Json(payload): Json<Value>, |
||||||
|
) -> Result<Json<EchoResponse>, ErrorResponse> { |
||||||
|
let response = EchoResponse { |
||||||
|
data: payload, |
||||||
|
timestamp: Utc::now().to_rfc3339(), |
||||||
|
}; |
||||||
|
Ok(Json(response)) |
||||||
|
} |
||||||
|
|
||||||
|
pub async fn version_handler(State(state): State<Arc<AppState>>) -> Json<VersionResponse> { |
||||||
|
Json(VersionResponse { |
||||||
|
name: state.name.clone(), |
||||||
|
version: state.version.clone(), |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// --- Router ---
|
||||||
|
|
||||||
|
pub fn routes() -> Router<Arc<AppState>> { |
||||||
|
Router::new() |
||||||
|
.route("/echo", post(echo_handler)) |
||||||
|
.route("/version", get(version_handler)) |
||||||
|
} |
||||||
@ -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<Arc<AppState>>, |
|
||||||
Json(payload): Json<Value>, |
|
||||||
) -> Result<Json<EchoResponse>, ErrorResponse> { |
|
||||||
let response = EchoResponse { |
|
||||||
data: payload, |
|
||||||
timestamp: Utc::now().to_rfc3339(), |
|
||||||
}; |
|
||||||
Ok(Json(response)) |
|
||||||
} |
|
||||||
|
|
||||||
pub async fn version_handler(State(state): State<Arc<AppState>>) -> Json<VersionResponse> { |
|
||||||
Json(VersionResponse { |
|
||||||
name: state.name.clone(), |
|
||||||
version: state.version.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
@ -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<E: std::error::Error> From<E> for ErrorResponse { |
|
||||||
fn from(err: E) -> Self { |
|
||||||
Self { |
|
||||||
error: err.to_string(), |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
Loading…
Reference in new issue