A fun test project exploring Rust web development with the Axum framework. This is a learning playground for building REST APIs with modern Rust tooling.
- Fast & Efficient: Built with Rust and Axum for exceptional performance
- JWT Authentication: Secure token-based authentication with short-lived access tokens, rotating refresh tokens, and bcrypt password hashing
- Database Integration: PostgreSQL with SQLx for type-safe database operations
- Migration System: Database schema management with SQLx migrations
- Logging: Structured logging with tracing and tracing-subscriber
- Environment Configuration: Environment variable management with dotenvy
- Docker Support: Containerized deployment with Docker Compose
- Modern Tooling: Justfile for common development tasks
- Type Safety: Leverages Rust's type system for compile-time guarantees
- Rust Seeding: Type-safe database seeding with readable scripts
- Testing: Unit tests for pure logic, integration tests with isolated per-test databases via
sqlx::test
- Framework: Axum - Fast, ergonomic web framework
- Database: PostgreSQL with SQLx - Async SQL toolkit
- Authentication: jsonwebtoken - JWT token handling
- Password Hashing: bcrypt - Secure password hashing
- Token Hashing: sha2 - SHA-256 hashing for refresh tokens
- Randomness: rand - Cryptographically secure token generation
- Runtime: Tokio - Async runtime
- Serialization: Serde - Serialization framework
- Logging: Tracing - Application-level tracing
- Environment: Dotenvy - Environment variable loader
- DateTime: Chrono - Date and time handling
- Containerization: Docker & Docker Compose
- Testing: axum-test - In-process HTTP test client for Axum
- Rust (latest stable version)
- PostgreSQL (or Docker for containerized database)
- Docker & Docker Compose (optional, for full containerized development)
Create a .env file in the project root with the following variables:
DATABASE_URL=postgresql://postgres:password@localhost:5432/rust-axum-rest-api
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production- Clone the repository:
git clone https://github.com/yourusername/rust-axum-rest-api.git
cd rust-axum-rest-api- Build the project:
just build- Set up the database (create, migrate, and seed):
just setup- Start the development server:
just devThe API will be available at http://localhost:5000
For containerized development:
docker-compose up --buildThis API uses JWT (JSON Web Tokens) for authentication with bcrypt-hashed passwords.
- Access tokens expire after 15 minutes
- Refresh tokens expire after 7 days and are rotated on every use (one-time use)
- Refresh tokens are stored as SHA-256 hashes; only the plaintext is returned to the client
The seeded database includes these test users:
| Username | Password | |
|---|---|---|
john_doe |
john@example.com | password123 |
jane_smith |
jane@example.com | password123 |
admin |
admin@example.com | admin_secure |
- Register: Create a new user account
- Login: Receive a short-lived access token and a long-lived refresh token
- Use Access Token: Include in
Authorization: Bearer <access_token>header for protected routes - Refresh: Exchange a valid refresh token for a new access token and rotated refresh token
- Logout: Revoke the refresh token via
Authorization: Bearer <refresh_token>header
Development:
just dev- Start development server with databasejust dev-watch- Start development server with auto-reloadjust generate-jwt <user_id>- Generate JWT token for testing
Building & Testing:
just build- Build the projectjust build-release- Build optimized release versionjust check- Check code without buildingjust test- Run all tests (unit + integration)just test-unit- Run unit tests only (no database required)just test-integration- Run integration tests (requires database)just test-watch- Run tests in watch mode
Code Quality:
just clippy- Run Clippy linterjust fmt- Format codejust fmt-check- Check code formatting
Database Management:
just db-up- Start PostgreSQL containerjust db-down- Stop PostgreSQL containerjust db-reset- Reset database containerjust migrate- Run database migrationsjust migrate-revert- Revert last migrationjust seed- Seed database with sample datajust setup- Complete database setup (create + migrate + seed)
Utilities:
just clean- Clean build artifacts and stop containersjust db-info- Show database connection details
GET /- Health check with database status
POST /auth/login- Login with username/password (returns access token + refresh token)POST /auth/refresh- Exchange refresh token for a new access token + rotated refresh tokenPOST /auth/logout- Revoke refresh token (Authorization: Bearer <refresh_token>)
| Method | Endpoint | Auth Required | Description |
|---|---|---|---|
POST |
/user |
❌ | Register new user |
GET |
/users |
✅ | Get all users |
GET |
/users/{id} |
✅ | Get user by ID |
GET |
/user |
✅ | Get current user profile |
PUT |
/user |
✅ | Update current user |
DELETE |
/user |
✅ | Delete current user |
| Method | Endpoint | Auth Required | Description |
|---|---|---|---|
GET |
/posts |
✅ | Get all posts |
GET |
/post/{id} |
✅ | Get post by ID |
POST |
/post |
✅ | Create new post |
PUT |
/post/{id} |
✅ | Update post (owner only) |
DELETE |
/post/{id} |
✅ | Delete post (owner only) |
GET |
/user/{id}/posts |
✅ | Get posts by user ID |
GET |
/user/posts |
✅ | Get current user's posts |
For protected endpoints, include the access token:
Authorization: Bearer <access_token>
For logout, include the refresh token instead:
Authorization: Bearer <refresh_token>
Error Responses:
401 Unauthorized- Missing, invalid, or expired token403 Forbidden- Valid token but insufficient permissions
This project is licensed under the MIT License - see the LICENSE file for details.