Structured Learning Path
This curriculum is designed to take you from a RustAPI beginner to an advanced user capable of building production-grade microservices.
Phase 1: Foundations
Goal: Build a simple CRUD API and understand the core request/response cycle.
Module 1: Introduction & Setup
- Prerequisites: Rust installed, basic Cargo knowledge.
- Reading: Installation, Project Structure.
- Task: Create a new project using
cargo rustapi new my-api. - Expected Output: A running server that responds to
GET /with “Hello World”. - Pitfalls: Not enabling
tokiofeatures if setting up manually.
🛠️ Mini Project: “The Echo Server”
Create a new endpoint POST /echo that accepts any text body and returns it back to the client. This verifies your setup handles basic I/O correctly.
🧠 Knowledge Check
- What command scaffolds a new RustAPI project?
- Which feature flag is required for the async runtime?
- Where is the main entry point of the application typically located?
Module 2: Routing & Handlers
- Prerequisites: Module 1.
- Reading: Handlers & Extractors.
- Task: Create routes for
GET /users,POST /users,GET /users/{id}. - Expected Output: Endpoints that return static JSON data.
- Pitfalls: Forgetting to register routes in
main.rsif not using auto-discovery.
🛠️ Mini Project: “The Calculator”
Create an endpoint GET /add?a=5&b=10 that returns {"result": 15}. This practices query parameter extraction and JSON responses.
🧠 Knowledge Check
- Which macro is used to define a GET handler?
- How do you return a JSON response from a handler?
- What is the return type of a typical handler function?
Module 3: Extractors
- Prerequisites: Module 2.
- Reading: Handlers & Extractors.
- Task: Use
Path,Query, andJsonextractors to handle dynamic input. - Expected Output:
GET /users/{id}returns the ID.POST /usersechoes the JSON body. - Pitfalls: Consuming the body twice (e.g., using
JsonandBodyin the same handler).
🛠️ Mini Project: “The User Registry”
Create a POST /register endpoint that accepts a JSON body {"username": "...", "age": ...} and returns a welcome message using the username. Use the Json extractor.
🧠 Knowledge Check
- Which extractor is used for URL parameters like
/users/:id? - Which extractor parses the request body as JSON?
- Can you use multiple extractors in a single handler?
🏆 Phase 1 Capstone: “The Todo List API”
Objective: Build a simple in-memory Todo List API. Requirements:
GET /todos: List all todos.POST /todos: Create a new todo.GET /todos/:id: Get a specific todo.DELETE /todos/:id: Delete a todo.- Use
Stateto store the list in aMutex<Vec<Todo>>.
Phase 2: Core Development
Goal: Add real logic, validation, and documentation.
Module 4: State Management
- Prerequisites: Phase 1.
- Reading: State Extractor.
- Task: Create an
AppStatestruct with aMutex<Vec<User>>. Inject it into handlers. - Expected Output: A stateful API where POST adds a user and GET retrieves it (in-memory).
- Pitfalls: Using
std::sync::Mutexinstead oftokio::sync::Mutexin async code (thoughstdis fine for simple data).
🧠 Knowledge Check
- How do you inject global state into the application?
- Which extractor retrieves the application state?
- Why should you use
Arcfor shared state?
Module 4.5: Database Integration
- Prerequisites: Module 4.
- Reading: Database Integration.
- Task: Replace the in-memory
Mutex<Vec<User>>with a PostgreSQL connection pool (sqlx::PgPool). - Expected Output: Data persists across server restarts.
- Pitfalls: Blocking the async runtime with synchronous DB drivers (use
sqlxortokio-postgres).
🧠 Knowledge Check
- Why is connection pooling important?
- How do you share a DB pool across handlers?
- What is the benefit of compile-time query checking in SQLx?
Module 5: Validation
- Prerequisites: Module 4.
- Reading: Validation.
- Task: Add
#[derive(Validate)]to yourUserstruct. UseValidatedJson. - Expected Output: Requests with invalid email or short password return
422 Unprocessable Entity. - Pitfalls: Forgetting to add
#[validate]attributes to struct fields.
🧠 Knowledge Check
- Which trait must a struct implement to be validatable?
- What HTTP status code is returned on validation failure?
- How do you combine JSON extraction and validation?
Module 5.5: Error Handling
- Prerequisites: Module 5.
- Reading: Error Handling.
- Task: Create a custom
ApiErrorenum and implementIntoResponse. Return robust error messages. - Expected Output:
GET /users/999returns404 Not Foundwith a structured JSON error body. - Pitfalls: Exposing internal database errors (like SQL strings) to the client.
🧠 Knowledge Check
- What is the standard error type in RustAPI?
- How do you mask internal errors in production?
- What is the purpose of the
error_idfield?
Module 6: OpenAPI & HATEOAS
- Prerequisites: Module 5.
- Reading: OpenAPI, OpenAPI Refs, Pagination Recipe.
- Task: Add
#[derive(Schema)]to all DTOs. Use#[derive(Schema)]on a shared struct and reference it in multiple places. - Expected Output: Swagger UI at
/docsshowing full schema with shared components. - Pitfalls: Recursive schemas without
BoxorOption.
🧠 Knowledge Check
- What does
#[derive(Schema)]do? - How does RustAPI handle shared schema components?
- What is HATEOAS and why is it useful?
Module 6.5: File Uploads & Multipart
- Prerequisites: Module 6.
- Reading: File Uploads.
- Task: Create an endpoint
POST /uploadthat accepts a file and saves it to disk. - Expected Output:
curl -F file=@image.pnguploads the file. - Pitfalls: Loading large files entirely into memory (use streaming).
🧠 Knowledge Check
- Which extractor is used for file uploads?
- Why should you use
field.chunk()instead offield.bytes()? - How do you increase the request body size limit?
🏆 Phase 2 Capstone: “The Secure Blog Engine”
Objective: Enhance the Todo API into a Blog Engine. Requirements:
- Add
Postresource with title, content, and author. - Validate that titles are not empty and content is at least 10 chars.
- Add pagination to
GET /posts. - Enable Swagger UI to visualize the API.
Phase 3: Advanced Features
Goal: Security, Real-time, and Production readiness.
Module 7: Authentication (JWT & OAuth2)
- Prerequisites: Phase 2.
- Reading: JWT Auth Recipe, OAuth2 Client.
- Task:
- Implement a login route that returns a JWT.
- Protect user routes with
AuthUserextractor. - (Optional) Implement “Login with Google” using
OAuth2Client.
- Expected Output: Protected routes return
401 Unauthorizedwithout a valid token. - Pitfalls: Hardcoding secrets. Not checking token expiration.
🧠 Knowledge Check
- What is the role of the
AuthUserextractor? - How does OAuth2 PKCE improve security?
- Where should you store the JWT secret?
Module 8: Advanced Middleware
- Prerequisites: Module 7.
- Reading: Advanced Middleware.
- Task:
- Apply
RateLimitLayerto your login endpoint (10 requests/minute). - Add
DedupLayerto a payment endpoint. - Cache the response of a public “stats” endpoint.
- Apply
- Expected Output: Sending 11 login attempts results in
429 Too Many Requests. - Pitfalls: Caching responses that contain user-specific data.
🧠 Knowledge Check
- What header indicates when the rate limit resets?
- Why is request deduplication important for payments?
- Which requests are typically safe to cache?
Module 9: WebSockets & Real-time
- Prerequisites: Phase 2.
- Reading: WebSockets Recipe.
- Task: Create a chat endpoint where users can broadcast messages.
- Expected Output: Multiple clients connected via WS receiving messages in real-time.
- Pitfalls: Blocking the WebSocket loop with long-running synchronous tasks.
🧠 Knowledge Check
- How do you upgrade an HTTP request to a WebSocket connection?
- Can you share state between HTTP handlers and WebSocket handlers?
- What happens if a WebSocket handler panics?
Module 10: Production Readiness & Deployment
- Prerequisites: Phase 3.
- Reading: Production Tuning, Resilience, Deployment.
- Task:
- Add
CompressionLayer, andTimeoutLayer. - Use
cargo rustapi deploy dockerto generate a Dockerfile.
- Add
- Expected Output: A resilient API ready for deployment.
- Pitfalls: Setting timeouts too low for slow operations.
🧠 Knowledge Check
- Why is timeout middleware important?
- What command generates a production Dockerfile?
- How do you enable compression for responses?
Module 11: Background Jobs & Testing
- Prerequisites: Phase 3.
- Reading: Background Jobs Recipe, Testing Strategy.
- Task:
- Implement a job
WelcomeEmailJobthat sends a “Welcome” email (simulated withtokio::time::sleep). - Enqueue this job inside your
POST /registerhandler. - Write an integration test using
TestClientto verify the registration endpoint.
- Implement a job
- Expected Output: Registration returns 200 immediately (low latency); console logs show “Sending welcome email to …” shortly after (asynchronous). Tests pass.
- Pitfalls: Forgetting to start the job worker loop (
JobWorker::new(queue).run().await).
🛠️ Mini Project: “The Email Worker”
Create a system where users can request a “Report”.
POST /reports: Enqueues aGenerateReportJob. Returns{"job_id": "..."}immediately.- The job simulates 5 seconds of work and then writes “Report Generated” to a file or log.
- (Bonus) Use Redis backend for persistence.
🧠 Knowledge Check
- Why should you offload email sending to a background job?
- Which backend is suitable for local development vs production?
- How do you enqueue a job from a handler?
- How can you test that a job was enqueued without actually running it?
🏆 Phase 3 Capstone: “The Real-Time Collaboration Tool”
Objective: Build a real-time collaborative note-taking app. Requirements:
- Auth: Users must log in (JWT or OAuth2) to edit notes.
- Real-time: Changes to a note are broadcast to all viewers via WebSockets.
- Jobs: When a note is deleted, schedule a background job to archive it (simulate archive).
- Resilience: Rate limit API requests to prevent abuse.
- Deployment: specify a
Dockerfilefor the application.
Phase 4: Enterprise Scale
Goal: Build observable, resilient, and high-performance distributed systems.
Module 12: Observability & Auditing
- Prerequisites: Phase 3.
- Reading: Observability (Extras), Audit Logging.
- Task:
- Enable
structured-loggingandotel. - Configure tracing to export spans.
- Implement
AuditStoreand log a “User Login” event with IP address.
- Enable
- Expected Output: Logs are JSON formatted. Audit log contains a new entry for every login.
- Pitfalls: High cardinality in metric labels.
🧠 Knowledge Check
- What is the difference between logging and auditing?
- Which fields are required in an
AuditEvent? - How does structured logging aid debugging?
Module 13: Resilience & Security
- Prerequisites: Phase 3.
- Reading: Resilience Patterns, Time-Travel Debugging.
- Task:
- Wrap an external API call with a
CircuitBreaker. - Implement
RetryLayerfor transient failures. - (Optional) Use
ReplayLayerto record and replay a tricky bug scenario.
- Wrap an external API call with a
- Expected Output: System degrades gracefully when external service is down. Replay file captures the exact request sequence.
- Pitfalls: Infinite retry loops or retrying non-idempotent operations.
🧠 Knowledge Check
- What state does a Circuit Breaker have when it stops traffic?
- Why is jitter important in retry strategies?
- How does Time-Travel Debugging help with “Heisenbugs”?
Module 14: High Performance
- Prerequisites: Phase 3.
- Reading: HTTP/3 (QUIC), Performance Tuning, Compression.
- Task:
- Enable
http3feature and generate self-signed certs. - Serve traffic over QUIC.
- Add
CompressionLayerto compress large responses.
- Enable
- Expected Output: Browser/Client connects via HTTP/3. Responses have
content-encoding: gzip. - Pitfalls: Compressing small responses (waste of CPU) or already compressed data (images).
🧠 Knowledge Check
- What transport protocol does HTTP/3 use?
- How does
simd-jsonimprove performance? - Why shouldn’t you compress JPEG images?
🏆 Phase 4 Capstone: “The High-Scale Event Platform”
Objective: Architect a system capable of handling thousands of events per second. Requirements:
- Ingestion: HTTP/3 endpoint receiving JSON events.
- Processing: Push events to a
rustapi-jobsqueue (Redis backend). - Storage: Workers process events and store aggregates in a database.
- Observability: Full tracing from ingestion to storage.
- Audit: Log all configuration changes to the system.
- Resilience: Circuit breakers on database writes.
- Testing: Load test the ingestion endpoint (e.g., with k6 or similar) and observe metrics.
Phase 5: Specialized Skills
Goal: Master integration with AI, gRPC, and server-side rendering.
Module 15: Server-Side Rendering (SSR)
- Prerequisites: Phase 2.
- Reading: SSR Recipe.
- Task: Create a dashboard showing system status using
rustapi-view. - Expected Output: HTML page rendered with Tera templates, displaying dynamic data.
- Pitfalls: Forgetting to create the
templates/directory.
🧠 Knowledge Check
- Which template engine does RustAPI use?
- How do you pass data to a template?
- How does template reloading work in debug mode?
Module 16: gRPC Microservices
- Prerequisites: Phase 3.
- Reading: gRPC Recipe.
- Task: Run a gRPC service alongside your HTTP API that handles internal user lookups.
- Expected Output: Both servers running; HTTP endpoint calls gRPC method (simulated).
- Pitfalls: Port conflicts if not configured correctly.
🧠 Knowledge Check
- Which crate provides gRPC helpers for RustAPI?
- Can HTTP and gRPC share the same Tokio runtime?
- Why might you want to run both in the same process?
Module 17: AI Integration (TOON)
- Prerequisites: Phase 2.
- Reading: AI Integration Recipe.
- Task: Create an endpoint that returns standard JSON for browsers but TOON for
Accept: application/toon. - Expected Output:
curlrequests with different headers return different formats. - Pitfalls: Not checking the
Acceptheader in client code.
🧠 Knowledge Check
- What is TOON and why is it useful for LLMs?
- How does
LlmResponsedecide which format to return? - How much token usage can TOON save on average?
🏆 Phase 5 Capstone: “The Intelligent Dashboard”
Objective: Combine SSR, gRPC, and AI features. Requirements:
- Backend: Retrieve stats via gRPC from a “worker” service.
- Frontend: Render a dashboard using SSR.
- AI Agent: Expose a TOON endpoint for an AI agent to query the system status.
Next Steps
- Explore the Examples Repository.
- Contribute a new recipe to the Cookbook!