use product_os_server::{ProductOSServer, StatusCode, Json};
use product_os_server::ServerConfig;
use product_os_async_executor::TokioExecutor;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone)]
struct User {
id: u32,
name: String,
email: String,
}
#[derive(Deserialize)]
struct CreateUserRequest {
name: String,
email: String,
}
async fn list_users() -> Result<Json<Vec<User>>, StatusCode> {
let users = vec![
User {
id: 1,
name: "Alice".to_string(),
email: "alice@example.com".to_string(),
},
User {
id: 2,
name: "Bob".to_string(),
email: "bob@example.com".to_string(),
},
];
Ok(Json(users))
}
async fn get_user() -> Result<Json<User>, StatusCode> {
Ok(Json(User {
id: 1,
name: "Alice".to_string(),
email: "alice@example.com".to_string(),
}))
}
async fn create_user(Json(req): Json<CreateUserRequest>) -> Result<Json<User>, StatusCode> {
let new_user = User {
id: 3,
name: req.name,
email: req.email,
};
Ok(Json(new_user))
}
async fn update_user(Json(user): Json<User>) -> Result<Json<User>, StatusCode> {
Ok(Json(user))
}
async fn delete_user() -> Result<StatusCode, StatusCode> {
Ok(StatusCode::NO_CONTENT)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
let mut config = ServerConfig::new();
config.network.port = 3000;
println!("Creating JSON API server...");
let mut server: ProductOSServer<(), TokioExecutor, _> =
ProductOSServer::new_with_config(config);
server.add_get("/api/users", list_users);
server.add_get("/api/users/1", get_user);
server.add_post("/api/users", create_user);
server.add_post("/api/users/1", update_user);
use product_os_server::Method;
server.add_handler("/api/users/1", Method::DELETE, delete_user);
println!("JSON API listening on http://localhost:3000");
println!("Try:");
println!(" curl http://localhost:3000/api/users");
println!(" curl http://localhost:3000/api/users/1");
println!(" curl -X POST -H 'Content-Type: application/json' -d '{{\"name\":\"Charlie\",\"email\":\"charlie@example.com\"}}' http://localhost:3000/api/users");
server.start(false).await.map_err(|e| format!("Server error: {}", e))?;
loop {
tokio::time::sleep(std::time::Duration::from_secs(3600)).await;
}
}