📖 Scenario: You are building a simple web API for a bookstore. Over time, you want to add new features without breaking existing clients. To do this, you will create two versions of the API endpoints using FastAPI.
🎯 Goal: Build a FastAPI application that supports two API versions: v1 and v2. Each version will have a /books endpoint returning different data formats. You will learn how to organize routes to handle versioning cleanly.
📋 What You'll Learn
Create a FastAPI app with two routers for versions v1 and v2
Define a /books GET endpoint in each version router
Return a list of books with different fields in v1 and v2
Mount the routers under /api/v1 and /api/v2 paths
💡 Why This Matters
🌍 Real World
APIs often need to evolve without breaking existing clients. Versioning helps manage changes safely.
💼 Career
Understanding API versioning is essential for backend developers working on web services and microservices.
Progress0 / 4 steps
1
Create initial book data
Create a list called books with two dictionaries. Each dictionary should have keys id and title with these exact values: {'id': 1, 'title': '1984'} and {'id': 2, 'title': 'Brave New World'}.
FastAPI
Hint
Use a list with two dictionaries exactly as shown.
2
Set up FastAPI app and routers
Import FastAPI and APIRouter from fastapi. Create a FastAPI app called app. Create two routers called router_v1 and router_v2 using APIRouter().
FastAPI
Hint
Remember to import both FastAPI and APIRouter and create the app and routers with exact names.
3
Define versioned /books endpoints
Add a GET endpoint /books to router_v1 that returns the books list as is. Add a GET endpoint /books to router_v2 that returns a list of books with id, title, and a new key author with value 'Unknown' for each book.
FastAPI
Hint
Use list comprehension to add the author key in v2.
4
Mount routers with version prefixes
Mount router_v1 on /api/v1 and router_v2 on /api/v2 using app.include_router().
FastAPI
Hint
Use app.include_router() with the prefix argument for versioning.
Practice
(1/5)
1. What is the main purpose of API versioning in FastAPI?
easy
A. To automatically generate API documentation
B. To speed up the API response time
C. To allow multiple versions of an API to coexist and support different clients
D. To encrypt API data for security
Solution
Step 1: Understand API versioning concept
API versioning lets you keep old and new API versions available so different clients can use the version they need.
Step 2: Identify the main goal
The main goal is to support multiple API versions simultaneously without breaking existing clients.
Final Answer:
To allow multiple versions of an API to coexist and support different clients -> Option C
Quick Check:
API versioning = support multiple versions [OK]
Hint: API versioning means supporting old and new API versions [OK]
Common Mistakes:
Thinking versioning speeds up API
Confusing versioning with security encryption
Assuming versioning auto-generates docs
2. Which of the following is a correct way to define a versioned route in FastAPI using the URL path method?
easy
A. app.get('/items/v1')
B. app.get('/v1/items/')
C. app.get('v1items/')
D. app.get('items/v1')
Solution
Step 1: Check route path syntax
FastAPI routes must start with a slash '/' to be valid paths.
Step 2: Identify correct version prefix
Versioning by URL path usually prefixes the version like '/v1/' before the resource path.
Final Answer:
app.get('/v1/items/') -> Option B
Quick Check:
Versioned route starts with '/' and version prefix [OK]
Hint: Routes must start with '/' and include version prefix [OK]
Common Mistakes:
Omitting leading slash in route path
Placing version after resource path incorrectly
Using quotes without leading slash
3. Given this FastAPI code snippet, what will be the response when accessing /api/items with header X-API-Version: 2?
The function reads the header 'X-API-Version' and compares it to '1' or '2'.
Step 2: Match header '2' to response
Since header is '2', it returns the dictionary with version 2 and items ['orange', 'grape'].
Final Answer:
{'version': 2, 'items': ['orange', 'grape']} -> Option D
Quick Check:
Header 'X-API-Version: 2' returns version 2 data [OK]
Hint: Match header value to if-elif branches for output [OK]
Common Mistakes:
Ignoring header and returning default
Confusing version 1 and 2 outputs
Assuming 404 error instead of 400
4. Identify the error in this FastAPI versioning code using query parameters:
from fastapi import FastAPI
app = FastAPI()
@app.get('/items')
async def read_items(version: int = 1):
if version == 1:
return {'items': ['pen', 'notebook']}
elif version == 2:
return {'items': ['pencil', 'eraser']}
else:
return {'error': 'Unsupported version'}
medium
A. The function should raise HTTPException for unsupported versions instead of returning dict
B. The query parameter 'version' should be declared with Query() for validation
C. The route path should include the version like '/v1/items'
D. The default version value should be a string, not int
Solution
Step 1: Check error handling for unsupported versions
Returning a dict with 'error' key is not standard; better to raise HTTPException with status code.
Step 2: Understand FastAPI error response best practice
Raising HTTPException sends proper HTTP error status and message to client.
Final Answer:
The function should raise HTTPException for unsupported versions instead of returning dict -> Option A
Quick Check:
Use HTTPException for errors, not plain dict [OK]
Hint: Use HTTPException for errors, not just return dict [OK]
Common Mistakes:
Returning error dict instead of raising exception
Thinking query parameter must use Query() always
Assuming version must be in URL path
5. You want to support two API versions in FastAPI: version 1 uses URL path versioning like /v1/users, and version 2 uses header versioning with X-API-Version: 2 on the same /users path. How can you implement this correctly?
hard
A. Create two separate routes: one with path '/v1/users' for version 1, and one with path '/users' that checks header 'X-API-Version' for version 2
B. Use a single route '/users' and check both path and header to decide version
C. Use only header versioning for both versions on '/users' path
D. Use query parameter 'version' for both versions on '/users' path
Solution
Step 1: Separate version 1 and version 2 routes
Version 1 uses URL path '/v1/users', so define a route with that path.
Step 2: Define version 2 route with header check
Version 2 uses header on '/users', so define a route '/users' that reads 'X-API-Version' header to confirm version 2.
Final Answer:
Create two separate routes: one with path '/v1/users' for version 1, and one with path '/users' that checks header 'X-API-Version' for version 2 -> Option A
Quick Check:
Separate routes for different versioning methods [OK]
Hint: Separate routes for path and header versioning [OK]
Common Mistakes:
Mixing path and header versioning in one route
Using only header or only path for both versions
Trying to detect path version inside header route
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.