//! {{TOOL_NAME}} REST API //! //! HTTP API server for {{TOOL_NAME}}. use axum::{ extract::{Path, State}, http::StatusCode, routing::{get, post, put, delete}, Json, Router, }; use serde::{Deserialize, Serialize}; use std::sync::Arc; use {{TOOL_NAME}}_core::*; #[derive(Clone)] struct AppState { service: {{MainType}}Service, } #[derive(Serialize, Deserialize)] struct CreateRequest { name: String, description: String, } #[tokio::main] async fn main() -> Result<()> { // Initialize logging tracing_subscriber::fmt() .with_env_filter("info") .init(); let state = AppState { service: {{MainType}}Service::new(), }; let app = Router::new() .route("/health", get(health_check)) .route("/{{main_type_plural}}", get(list_items).post(create_item)) .route("/{{main_type_plural}}/:id", get(get_item).put(update_item).delete(delete_item)) .with_state(Arc::new(state)); let listener = tokio::net::TcpListener::bind("127.0.0.1:3000") .await .expect("Failed to bind port 3000"); tracing::info!("Server listening on http://127.0.0.1:3000"); axum::serve(listener, app) .await .expect("Server error"); Ok(()) } async fn health_check() -> StatusCode { StatusCode::OK } async fn list_items(State(state): State>) -> Json> { match state.service.list().await { Ok(items) => Json(items), Err(_) => Json(vec![]), } } async fn get_item( State(state): State>, Path(id): Path, ) -> Result, StatusCode> { state.service.get(&id).await .map(Json) .map_err(|_| StatusCode::NOT_FOUND) } async fn create_item( State(state): State>, Json(req): Json, ) -> Result, StatusCode> { state.service.create(req.name, req.description).await .map(Json) .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR) } async fn update_item( State(state): State>, Path(id): Path, Json(req): Json, ) -> Result, StatusCode> { state.service.update(&id, req.name, req.description).await .map(Json) .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR) } async fn delete_item( State(state): State>, Path(id): Path, ) -> StatusCode { match state.service.delete(&id).await { Ok(_) => StatusCode::NO_CONTENT, Err(_) => StatusCode::NOT_FOUND, } }