Merge _configs/ into config/ for single configuration directory. Update all path references. Changes: - Move _configs/* to config/ - Update .gitignore for new patterns - No code references to _configs/ found Impact: -1 root directory (layout_conventions.md compliance)
104 lines
2.5 KiB
Plaintext
104 lines
2.5 KiB
Plaintext
//! {{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<Arc<AppState>>) -> Json<Vec<{{MainType}}>> {
|
|
match state.service.list().await {
|
|
Ok(items) => Json(items),
|
|
Err(_) => Json(vec![]),
|
|
}
|
|
}
|
|
|
|
async fn get_item(
|
|
State(state): State<Arc<AppState>>,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<{{MainType}}>, StatusCode> {
|
|
state.service.get(&id).await
|
|
.map(Json)
|
|
.map_err(|_| StatusCode::NOT_FOUND)
|
|
}
|
|
|
|
async fn create_item(
|
|
State(state): State<Arc<AppState>>,
|
|
Json(req): Json<CreateRequest>,
|
|
) -> Result<Json<{{MainType}}>, StatusCode> {
|
|
state.service.create(req.name, req.description).await
|
|
.map(Json)
|
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)
|
|
}
|
|
|
|
async fn update_item(
|
|
State(state): State<Arc<AppState>>,
|
|
Path(id): Path<String>,
|
|
Json(req): Json<CreateRequest>,
|
|
) -> Result<Json<{{MainType}}>, 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<Arc<AppState>>,
|
|
Path(id): Path<String>,
|
|
) -> StatusCode {
|
|
match state.service.delete(&id).await {
|
|
Ok(_) => StatusCode::NO_CONTENT,
|
|
Err(_) => StatusCode::NOT_FOUND,
|
|
}
|
|
}
|