A complete REST API built with Axum, SQLx, PostgreSQL, and Swagger UI documentation.
- ✅ Full CRUD operations
- ✅ PostgreSQL database with SQLx
- ✅ Automatic database migrations
- ✅ Request logging and tracing
- ✅ CORS support
- ✅ Interactive Swagger UI documentation
- ✅ OpenAPI 3.0 specification
- Rust (latest stable)
- PostgreSQL database
-
Clone the repository
-
Copy
.env.exampleto.envand update the database URL:cp .env.example .env
-
Create a PostgreSQL database:
CREATE DATABASE mydb;
-
Run the application (migrations run automatically):
cargo run
-
Open Swagger UI at: http://localhost:3000/swagger-ui
Visit http://localhost:3000/swagger-ui for interactive API documentation where you can:
- View all available endpoints
- See request/response schemas
- Test API calls directly from the browser
- Download the OpenAPI specification
Access the raw OpenAPI spec at: http://localhost:3000/api-docs/openapi.json
GET /users- List all usersPOST /users- Create a new userGET /users/:id- Get user by IDPUT /users/:id- Update userDELETE /users/:id- Delete user
curl -X POST http://localhost:3000/users \
-H "Content-Type: application/json" \
-d '{"name": "John Doe", "email": "john@example.com"}'curl http://localhost:3000/userscurl http://localhost:3000/users/1curl -X PUT http://localhost:3000/users/1 \
-H "Content-Type: application/json" \
-d '{"name": "Jane Doe"}'curl -X DELETE http://localhost:3000/users/1src/
├── main.rs # Application entry point with OpenAPI setup
├── models.rs # Data models with schema annotations
├── db.rs # Database operations
├── handlers.rs # HTTP handlers with OpenAPI documentation
└── routes.rs # Route definitions
migrations/
└── 20240101000000_create_users.sql
- axum - Web framework
- tokio - Async runtime
- sqlx - Async PostgreSQL driver
- tower-http - HTTP middleware (CORS, tracing)
- utoipa - OpenAPI documentation generation
- utoipa-swagger-ui - Swagger UI integration
The Swagger UI automatically updates when you modify the API endpoints. Just restart the server to see your changes reflected in the documentation!
The easiest way to run the entire stack:
# Build and start both PostgreSQL and the API
docker-compose up --build
# Run in detached mode
docker-compose up -d --build
# View logs
docker-compose logs -f
# Stop services
docker-compose down
# Stop and remove volumes
docker-compose down -vThe API will be available at:
- Application: http://localhost:3000
- Swagger UI: http://localhost:3000/swagger-ui
If you want to build just the API container:
# Build the image
docker build -t axum-api .
# Run with external PostgreSQL
docker run -p 3000:3000 \
-e DATABASE_URL=postgres://user:pass@host:5432/db \
axum-apiThe Dockerfile uses a two-stage build:
-
Builder Stage (
rust:1.75-slim)- Installs build dependencies
- Compiles the Rust application in release mode
- Produces optimized binary
-
Runtime Stage (
scratch)- Minimal image with no OS
- Only contains the compiled binary and SSL certificates
- Extremely small image size (~10-15MB)
- Enhanced security with minimal attack surface
The docker-compose.yml sets up:
- PostgreSQL 16 Alpine (lightweight)
- Health checks to ensure database is ready
- Persistent volume for data
- Automatic network configuration
- Environment variables for easy configuration
For production deployments:
- Change default passwords in
docker-compose.yml - Use secrets management instead of environment variables
- Add resource limits:
deploy: resources: limits: cpus: '0.5' memory: 512M
- Use a reverse proxy (nginx, traefik) for SSL/TLS
- Enable database backups
- Consider using a managed PostgreSQL service