Skip to main content
Glama
main.rs4.28 kB
use axum::{ extract::{Path, State}, http::StatusCode, response::Json, routing::{get, post, delete}, Router, }; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::sync::{Arc, RwLock}; use tokio::net::TcpListener; // ============================================ // Models // ============================================ #[derive(Debug, Clone, Serialize)] pub struct User { pub id: u32, pub email: String, pub name: String, pub created_at: String, } #[derive(Debug, Deserialize)] pub struct CreateUserRequest { pub email: String, pub name: String, } #[derive(Debug, Serialize)] pub struct ApiResponse<T> { pub success: bool, #[serde(skip_serializing_if = "Option::is_none")] pub data: Option<T>, #[serde(skip_serializing_if = "Option::is_none")] pub error: Option<String>, } impl<T> ApiResponse<T> { fn success(data: T) -> Self { Self { success: true, data: Some(data), error: None } } fn error(msg: &str) -> Self { Self { success: false, data: None, error: Some(msg.to_string()) } } } // ============================================ // Database (Thread-Safe) // ============================================ #[derive(Default)] pub struct Database { users: RwLock<HashMap<u32, User>>, next_id: RwLock<u32>, } impl Database { pub fn new() -> Self { Self { users: RwLock::new(HashMap::new()), next_id: RwLock::new(1), } } pub fn create_user(&self, req: CreateUserRequest) -> User { let mut next_id = self.next_id.write().unwrap(); let id = *next_id; *next_id += 1; let user = User { id, email: req.email, name: req.name, created_at: chrono::Utc::now().to_rfc3339(), }; self.users.write().unwrap().insert(id, user.clone()); user } pub fn get_user(&self, id: u32) -> Option<User> { self.users.read().unwrap().get(&id).cloned() } pub fn get_all_users(&self) -> Vec<User> { self.users.read().unwrap().values().cloned().collect() } pub fn delete_user(&self, id: u32) -> bool { self.users.write().unwrap().remove(&id).is_some() } } type AppState = Arc<Database>; // ============================================ // Handlers // ============================================ async fn health() -> Json<serde_json::Value> { Json(serde_json::json!({ "status": "healthy", "timestamp": chrono::Utc::now().to_rfc3339() })) } async fn get_users(State(db): State<AppState>) -> Json<ApiResponse<Vec<User>>> { let users = db.get_all_users(); Json(ApiResponse::success(users)) } async fn create_user( State(db): State<AppState>, Json(req): Json<CreateUserRequest>, ) -> (StatusCode, Json<ApiResponse<User>>) { if req.email.is_empty() || req.name.is_empty() { return (StatusCode::BAD_REQUEST, Json(ApiResponse::error("Email and name required"))); } let user = db.create_user(req); (StatusCode::CREATED, Json(ApiResponse::success(user))) } async fn get_user( State(db): State<AppState>, Path(id): Path<u32>, ) -> Result<Json<ApiResponse<User>>, (StatusCode, Json<ApiResponse<User>>)> { match db.get_user(id) { Some(user) => Ok(Json(ApiResponse::success(user))), None => Err((StatusCode::NOT_FOUND, Json(ApiResponse::error("User not found")))), } } async fn delete_user_handler( State(db): State<AppState>, Path(id): Path<u32>, ) -> StatusCode { if db.delete_user(id) { StatusCode::NO_CONTENT } else { StatusCode::NOT_FOUND } } // ============================================ // Main // ============================================ #[tokio::main] async fn main() { let db = Arc::new(Database::new()); let app = Router::new() .route("/health", get(health)) .route("/api/users", get(get_users).post(create_user)) .route("/api/users/:id", get(get_user).delete(delete_user_handler)) .with_state(db); let listener = TcpListener::bind("0.0.0.0:8080").await.unwrap(); println!("Server running on http://localhost:8080"); axum::serve(listener, app).await.unwrap(); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/millsydotdev/Code-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server