commit 3693a1941115c7a90efb0a87c0afaf91100d6ae3 Author: Jonas Müller Date: Thu Jan 8 10:00:00 2026 +0000 Initial Rust/Axum API skeleton diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..a1df504 --- /dev/null +++ b/.env.example @@ -0,0 +1,5 @@ +DATABASE_URL=postgres://nexus:@localhost:5432/nexus_dev +JWT_SECRET= +JWT_EXPIRY_SECS=3600 +PORT=8080 +RUST_LOG=info diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e3a21e5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/target +.env +*.log +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..2ff2686 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "nexus-api" +version = "1.3.0" +edition = "2021" + +[dependencies] +axum = "0.7" +tokio = { version = "1", features = ["full"] } +sqlx = { version = "0.7", features = ["postgres", "runtime-tokio", "uuid", "time"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" +uuid = { version = "1", features = ["v4"] } +jsonwebtoken = "9" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +tower = "0.4" +tower-http = { version = "0.5", features = ["trace", "cors"] } +anyhow = "1" +thiserror = "1" + +[dev-dependencies] +tokio-test = "0.4" +reqwest = { version = "0.12", features = ["json"] } diff --git a/README.md b/README.md new file mode 100644 index 0000000..414df44 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# nexus/backend-api + +Core REST API for the Nexus platform. Built with Rust (Axum). + +## Development + + cargo build + cargo test + cargo run -- --port 8080 + +## Environment + +Copy `.env.example` to `.env` before running locally. + +## API Reference + +| Endpoint | Method | Description | +|----------|--------|-------------| +| `/health` | GET | Liveness check | +| `/api/v1/users` | GET | List users | +| `/api/v1/users/:id` | GET | Get user by ID | +| `/api/v1/auth/login` | POST | Authenticate | +| `/api/v1/auth/refresh` | POST | Refresh JWT | + +## Architecture + +Request → Axum router → middleware (auth, logging) → handler → SQLx → PostgreSQL diff --git a/src/api/health.rs b/src/api/health.rs new file mode 100644 index 0000000..1ac73d1 --- /dev/null +++ b/src/api/health.rs @@ -0,0 +1,6 @@ +use axum::{http::StatusCode, Json}; +use serde_json::{json, Value}; + +pub async fn health_check() -> (StatusCode, Json) { + (StatusCode::OK, Json(json!({ "status": "ok", "version": env!("CARGO_PKG_VERSION") }))) +} diff --git a/src/api/mod.rs b/src/api/mod.rs new file mode 100644 index 0000000..72983d9 --- /dev/null +++ b/src/api/mod.rs @@ -0,0 +1,3 @@ +pub mod health; +pub mod users; +pub mod auth; diff --git a/src/models/user.rs b/src/models/user.rs new file mode 100644 index 0000000..ef7f8e2 --- /dev/null +++ b/src/models/user.rs @@ -0,0 +1,16 @@ +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)] +pub struct User { + pub id: Uuid, + pub username: String, + pub email: String, +} + +#[derive(Debug, Deserialize)] +pub struct CreateUserRequest { + pub username: String, + pub email: String, + pub password: String, +}