Consider this FastAPI app with two versions of the same endpoint using path versioning:
from fastapi import FastAPI
app = FastAPI()
@app.get('/v1/items')
async def get_items_v1():
return {'version': 'v1', 'items': [1, 2, 3]}
@app.get('/v2/items')
async def get_items_v2():
return {'version': 'v2', 'items': ['a', 'b', 'c']}What will be the JSON response when a client requests /v1/items?
from fastapi import FastAPI app = FastAPI() @app.get('/v1/items') async def get_items_v1(): return {'version': 'v1', 'items': [1, 2, 3]} @app.get('/v2/items') async def get_items_v2(): return {'version': 'v2', 'items': ['a', 'b', 'c']}
Check which function handles the /v1/items path.
The endpoint /v1/items is handled by get_items_v1 which returns version 'v1' and a list of numbers.
You want to create a FastAPI endpoint that returns different responses based on a custom header X-API-Version. Which code snippet correctly reads this header and returns the version?
Use FastAPI's Header dependency to read headers.
Option A correctly uses Header(...) to declare a required header parameter. Option A misses the Header dependency, C uses wrong syntax, and D lacks request context.
Given this FastAPI app using query parameter for versioning:
from fastapi import FastAPI, Query, HTTPException
app = FastAPI()
@app.get('/items')
async def get_items(version: str = Query(None)):
if version == '1':
return {'version': 'v1', 'items': [1, 2]}
elif version == '2':
return {'version': 'v2', 'items': ['a', 'b']}
else:
raise HTTPException(status_code=400, detail='Invalid or missing version')What happens if a client calls /items without the version query parameter?
from fastapi import FastAPI, Query, HTTPException app = FastAPI() @app.get('/items') async def get_items(version: str = Query(None)): if version == '1': return {'version': 'v1', 'items': [1, 2]} elif version == '2': return {'version': 'v2', 'items': ['a', 'b']} else: raise HTTPException(status_code=400, detail='Invalid or missing version')
Check the else branch when version is None.
If the version query parameter is missing, the function raises an HTTP 400 error with the given detail.
Examine this FastAPI app using APIRouter with prefix for versioning:
from fastapi import FastAPI, APIRouter
app = FastAPI()
v1_router = APIRouter(prefix='/v1')
@v1_router.get('/items')
async def get_items_v1():
return {'version': 'v1'}
app.include_router(v1_router)
@app.get('/items')
async def get_items_default():
return {'version': 'default'}Requests to /v1/items return 404. What is the likely cause?
from fastapi import FastAPI, APIRouter app = FastAPI() v1_router = APIRouter(prefix='/v1') @v1_router.get('/items') async def get_items_v1(): return {'version': 'v1'} app.include_router(v1_router) @app.get('/items') async def get_items_default(): return {'version': 'default'}
Check how prefix is applied when including routers.
The prefix is correctly set in APIRouter constructor, but if include_router is called without arguments, the prefix applies. If the router was included without prefix, the route would be '/items' only. Here, the code is correct, so the 404 likely means the router was not included properly or the server was not restarted.
But since the code shows correct usage, the most common cause is that the router was included without prefix argument, which is not the case here. So the question is tricky: the code is correct, so the 404 is unexpected.
However, the question states requests to '/v1/items' return 404. The only cause is that the router was included without prefix, meaning the prefix was not applied. So the likely cause is that the router was included without prefix, which contradicts the code snippet. So the best answer is A.
Among these API versioning strategies, which one is best suited to maintain backward compatibility while allowing clients to migrate gradually?
- Path versioning (e.g., /v1/resource)
- Header versioning (e.g., X-API-Version header)
- Query parameter versioning (e.g., ?version=1)
- Content negotiation (Accept header with version)
Think about how clients can keep using old versions while moving to new ones.
Path versioning clearly separates versions by URL, allowing old clients to keep using old paths while new clients use new paths. This supports backward compatibility and gradual migration. Other methods may be more flexible but can cause confusion or require clients to handle version negotiation carefully.