Jesús Pérez 9cef9b8d57 refactor: consolidate configuration directories
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)
2025-12-26 18:36:23 +00:00

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,
}
}