Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
Jared Bell 20a4ca698e Initial commit vor 2 Wochen
config Initial commit vor 2 Wochen
src Initial commit vor 2 Wochen
tests Initial commit vor 2 Wochen
.env.example Initial commit vor 2 Wochen
.gitignore Initial commit vor 2 Wochen
Cargo.lock Initial commit vor 2 Wochen
Cargo.toml Initial commit vor 2 Wochen
README.md Initial commit vor 2 Wochen

README.md

axum-api-template

An opinionated Axum web API template modelled after the ASP.NET project layout.

Philosophy

ASP.NET concept This template
Program.cs bootstrap src/main.rs
appsettings.json + env overrides config/*.toml + APP__* env vars
IServiceCollection / DI AppState (shared via Axum State extractor)
Controller classes src/handlers/ — one file per resource
Request / Response DTOs src/models/*Request / *Response suffix convention
ProblemDetails src/errors/ApiError — single IntoResponse impl
app.Use* middleware pipeline src/routes/mod.rs build_router()
Route groups (MapGroup) src/routes/v1.rs nested routers

Project layout

axum-api-template/
├── config/
│   ├── default.toml        # base config (committed)
│   ├── development.toml    # dev overrides (committed)
│   └── production.toml     # prod overrides (committed; no secrets)
├── src/
│   ├── main.rs             # entry point — startup sequence
│   ├── lib.rs              # re-exports all modules for integration tests
│   ├── config/             # AppConfig (layered TOML + env vars)
│   ├── errors/             # ApiError → consistent JSON error envelope
│   ├── handlers/
│   │   ├── health.rs       # GET /health/live, /health/ready
│   │   └── items.rs        # full CRUD scaffold for an example resource
│   ├── middleware/
│   │   ├── auth.rs         # AuthenticatedUser extractor (JWT stub)
│   │   └── request_id.rs   # X-Request-ID documentation anchor
│   ├── models/
│   │   ├── item.rs         # Item domain struct + CreateItemRequest + ItemResponse
│   │   └── pagination.rs   # PaginationQuery + PagedResponse<T>
│   ├── routes/
│   │   ├── mod.rs          # build_router() — middleware stack assembly
│   │   └── v1.rs           # /api/v1/* route table
│   └── state/              # AppState (Arc<InnerState>)
├── tests/
│   ├── common/mod.rs       # shared test helpers (TestServer factory)
│   └── health_test.rs      # integration tests for /health/*
├── .env.example
├── .gitignore
└── Cargo.toml

Quickstart

cp .env.example .env
# Edit .env — at minimum set APP__DATABASE__URL

cargo run
# → Listening on 0.0.0.0:8080

Configuration

Configuration is resolved in order of increasing precedence:

  1. config/default.toml
  2. config/{APP_ENV}.toml (set APP_ENV=production in your environment)
  3. Environment variables prefixed APP__ with double-underscore separators
# Examples
APP__SERVER__PORT=9000
APP__DATABASE__URL=postgres://user:pass@db/myapp
APP__AUTH__JWT_SECRET=super-secret

Naming conventions

Thing Convention Example
Handler functions verb_resource list_items, create_item
Request DTOs {Resource}CreateRequest CreateItemRequest
Response DTOs {Resource}Response ItemResponse
Route modules version-namespaced routes/v1.rs
Config env vars APP__{SECTION}__{KEY} APP__SERVER__PORT
Error variants PascalCase domain names ApiError::NotFound

Endpoints

Method Path Description
GET /health/live Liveness check
GET /health/ready Readiness check (dependency health)
GET /api/v1/items List items (paginated)
POST /api/v1/items Create item
GET /api/v1/items/:id Get item by ID
PUT /api/v1/items/:id Update item
DELETE /api/v1/items/:id Delete item

Error shape

All errors return a consistent JSON envelope:

{
  "error": {
    "status": 404,
    "code": "NOT_FOUND",
    "message": "Item 00000000-0000-0000-0000-000000000001 not found",
    "trace_id": "01924b72-1234-7abc-def0-000000000000"
  }
}

Next steps