An example API built with Rust, Axum, SQLx, S3, Redis, and PostgreSQL.
β οΈ Warning: This project is under active development. Pushed changes have been tested. But it might not yet be production ready.
Axium is a high-performance, security-focused API boilerplate built using Rust, Axum, SQLx, S3, Redis, and PostgreSQL.
It provides a ready-to-deploy solution with modern best practices, including JWT authentication, role-based access control (RBAC), structured logging, and enterprise-grade security. With a focus on developer experience, Axium offers auto-generated API documentation, efficient database interactions, and an ergonomic code structure for ease of maintenance and scalability.
The project uses its own routing wrapper built on top of Axum. The wrapper was created to simplify the integration of the RBAC and unify the passing of connections to external services (database, Redis, S3).
- π¦ Axium
- Summary
- Table of Contents
- π Core Features
- π οΈ Technology stack
- π Project structure
- π Default API endpoints
- | GET |
/referencedata/{countries/languages}| π« | π« | Public endpoint meant to support a frontend, for example to fill select/dropdown objects. - π¦ Installation & usage
- Integration
From zero to production in minutes
- π³ Docker Compose stack with pre-configured services
- 20-minute setup timeline with
docker-compose upsimplicity
Spec-driven development workflow
- Auto-generated OpenAPI 3.1 specifications
- Interactive Swagger UI endpoint at
/docs - Custom wrapper for a simpler implementation of RBAC (which extends Axum) following the DRY principle (Don't repeat yourself)
Security by design architecture
- JWT authentication with Argon2id password hashing (OWASP recommended)
- TLS 1.3/HTTP2 via AWS-LC (FIPS 140-3 compliant cryptography)
- Key rotation & expiration
- Custom Role-Based Access Control (RBAC) implementation, (read more):
.get("/all", get_all_apikeys, vec![1, 2]) // Admins and users
))Relational data made simple
- SQLx-powered async database operations
- Migration system with transactional safety
- Connection pooling for high concurrency
- Lower stress on the database by checking the Redis cache first
Engineered for speed at scale
- Brotli compression (11-level optimization)
- Intelligent request caching strategies
Production monitoring made easy
- Docker-healthcheck / OpenTelemetry compatible endpoint:
{
"details": {
"cache": {
"status": "ok"
},
"cpu_usage": {
"available_percentage": "2.48",
"status": "low",
"usage_percentage": "97.52"
},
"database": {
"status": "ok"
},
"disk_usage": {
"status": "ok",
"used_percentage": "85.00"
},
"important_processes": [
{
"name": "postgres",
"status": "running"
},
{
"name": "minio",
"status": "running"
}
],
"memory": {
"available_mb": 17785,
"status": "normal"
},
"network": {
"status": "ok"
}
"storage": {
"status": "ok"
},
},
"status": "degraded"
}Code with confidence
- Context-aware user injection system:
pub async fn get_users_by_id(
State(state): State<Arc<AppState>>, // Database connection + storage connection
Path(id): Path<String>, // Path variables
Extension(current_user): Extension<User>, // Current user
) -> impl IntoResponse {
// Business logic with direct user context
}- Structured logging with OpenTelemetry integration
- Compile-time configuration validation
Future-proof codebase management
- Security-focused dependency tree (cargo-audit compliant)
- Comprehensive inline documentation
| Category | Key Technologies |
|---|---|
| Web Framework | Axum 0.8 + Tower |
| Database | PostgreSQL + SQLx 0.8 |
| Storage | S3 / MinIO |
| Security | JWT + Argon2 + Rustls + TOPTP |
| Monitoring | Tracing + Sysinfo |
axium/ # Root project directory
βββ migrations/ # Database schema migrations
βββ src/ # Application source code
β βββ core/ # Core application infrastructure
β βββ database/ # Database access layer (SQLx)
β βββ middlewares/ # Middleware components
β βββ routes/ # API endpoint routing
β βββ handlers/ # Request handlers
β βββ utils/ # Common utilities
β βββ wrappers/ # Wrapper implementations
β βββ cache/ # Caching mechanisms (Redis)
β βββ storage/ # Storage service integrations (S3 / MinIO)
β βββ main.rs # Application entry point
βββ documentation/ # Project documentation
βββ Bruno.json # API testing configuration for Bruno
βββ .env.example # Environment template
βββ Dockerfile # Production container build
βββ docker-compose.yml # Local development stack
βββ Cargo.toml # Rust dependencies & metadata
| Method | Endpoint | Auth Required | Administrator only | Description |
|---|---|---|---|---|
| POST | /login |
π« | π« | Authenticate user and get JWT token |
| POST | /register |
π« | π« | Create an user account. |
| POST | /register/verify |
π« | π« | Confirm the acount creation using the activation code sent to the user's email. |
| POST | /reset |
π« | π« | Request a password reset code to be sent to the user's email. |
| POST | /reset/verify |
π« | π« | Confirm password reset with code and set new password. |
| GET | /protected |
β | π« | Test endpoint for authenticated users |
| GET | /health |
π« | π« | System health check with metrics |
| Apikey routes | ||||
| GET | /apikeys/all |
β | π« | Get all apikeys of the current user. |
| POST | /apikeys/ |
β | π« | Create a new apikey. |
| GET | /apikeys/{id} |
β | π« | Get an apikey by ID. |
| DELETE | /apikeys/{id} |
β | π« | Delete an apikey by ID. |
| POST | /apikeys/rotate/{id} |
β | π« | Rotates an API key, disables the old one (grace period 24 hours), returns a new one. |
| User routes | ||||
| GET | /users/all |
β | β | Get all users. |
| POST | /users/ |
β | β | Create a new user. |
| POST | /users/{id}/profile-picture |
β | π«/β (see below) | Upload or update a user's profile picture. Will be converted to WebP, cropped to 300x300, max 10 MB, Admins can upload for others. |
| PATCH | /users/{id} |
β | π«/β (see below) | Update user profile fields (self or admin for others). |
| GET | /users/current |
β | π« | Get the current user. |
| GET | /users/{id} |
β | β | Get a user by ID. |
| DELETE | /users/{id} |
β | β | Delete a user by ID. |
| Usage routes | ||||
| GET | /usage/lastweek |
β | π« | Amount of API calls within the last week of the current user. |
| GET | /usage/lastday |
β | π« | Amount of API calls within last day of the current user. |
| Todo routes | ||||
| GET | /todos/all |
β | π« | Get all todos of the current user. |
| POST | /todos/ |
β | π« | Create a new todo. |
| GET | /todos/{id} |
β | π« | Get a todo by ID. |
| DELETE | /todos/{id} |
β | π« | Delete a todo by ID. |
| Other routes | ||||
| GET | /referencedata/{countries/languages} |
π« | π« | Public endpoint meant to support a frontend, for example to fill select/dropdown objects. |
- POST
/users/{id}/profile-pictureand PATCH/users/{id}:- Regular users can update their own profile or profile picture.
- Admins can update or upload for any user.
- Marked as "π«/β (see below)" to indicate both self and admin access.
- If you want to clarify this further, you can add a footnote or a new column for "Self or Admin".
To get started with Axium, you'll need to install it on your system. We provide detailed installation guides for different environments:
- Docker setup: Follow the instructions in Docker setup guide to run Axium using Docker Compose.
- Ubuntu setup: For users on Ubuntu or other Debian-based systems, refer to the Ubuntu setup Guide.
- Windows setup: Windows users can find their setup instructions in the Windows setup guide.
Make sure to have a PostgreSQL database and a S3 storage available. Both can be easily locally installed. We recommend MinIO, as the S3 storage for developing the API locally
These guides cover cloning the repository, setting up the environment, configuring the database, and running the application.
You can easily integrate Axium with your applications. Here is a detailed guide of integrating the authentication process in SolidJS:
We might add some more examples in the future. The SolidJS-example can be easily adapted for other JavaScript/TypeScript frameworks.
To authenticate, send a POST request to the /login endpoint with a JSON body in the following format:
{
"email": "admin@test.com",
"password": "test",
"totp": "12234" // Optional: only required if your account uses 2FA
}Depending on the server configuration, after a successful login:
-
You will receive a JWT token in the response body, and/or,
-
The server will set a secure, HTTP-only cookie containing your authentication token.
If you receive a JWT in the response body:
- Send it in the Authorization header for future requests:
Authorization: Bearer <your_token_here> - If you receive a cookie: Your browser will automatically send it with each request. No manual action is needed.
Warning: These accounts should only be used for initial testing. Always change or disable them in production environments.
| Password | Role | |
|---|---|---|
user@test.com |
test |
User |
admin@test.com |
test |
Administrator |
- Rotate passwords immediately after initial setup.
- Disable default accounts before deploying to production.
- Implement proper user management endpoints.
For emergency access recovery only
-
Database Access
Connect to PostgreSQL using privileged credentials:psql -U admin_user -d axium_db -h localhost
-
Secure Hash Generation
Use the integrated CLI tool (never user online generators):cargo run --bin argon2-cli -- "new_password" # Output: $argon2id$v=19$m=19456,t=2,p=1$b2JqZWN0X2lkXzEyMzQ1$R7Zx7Y4W...
-
Database Update
UPDATE users SET password_hash = '$argon2id...', updated_at = NOW() WHERE email = 'user@example.com';
-
Verification
- Immediately test new credentials
- Force user password change on next login
Most configuration options can be set using the .env file and the database tables that are being created during the first run (check out: /migrations).
As this project is a template we encourage you to tinker it to your hearts desire. First place to start in most cases is the handlers folder. Here you can define per endpoint what should happen. Afterwards you can easily integrate your new handler in one of the /routes.