Bird
Raised Fist0
FastAPIframework~20 mins

Custom middleware creation in FastAPI - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Middleware Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What does this FastAPI middleware log?

Consider this FastAPI middleware that logs request method and path. What will it print when a GET request is made to /items/5?

FastAPI
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware

app = FastAPI()

class LogMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        print(f"Request: {request.method} {request.url.path}")
        response = await call_next(request)
        return response

app.add_middleware(LogMiddleware)

@app.get('/items/{item_id}')
async def read_item(item_id: int):
    return {"item_id": item_id}
ARequest: GET /items/{item_id}
BRequest: POST /items/5
CRequest: GET /items/5
DNo output printed
Attempts:
2 left
💡 Hint

Look at the request.method and request.url.path values used in the print statement.

📝 Syntax
intermediate
2:00remaining
Identify the syntax error in this FastAPI middleware

Which option correctly identifies the syntax error in this middleware code?

FastAPI
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware

app = FastAPI()

class ErrorMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        response = await call_next(request)
        return response

app.add_middleware(ErrorMiddleware)

@app.get('/')
async def root():
    return {"message": "Hello"}
Adispatch method missing async keyword
BMissing closing parenthesis in app.add_middleware(ErrorMiddleware
CBaseHTTPMiddleware cannot be subclassed
DRequest parameter missing type annotation
Attempts:
2 left
💡 Hint

Check the parentheses in the app.add_middleware line.

state_output
advanced
2:00remaining
What is the response header after this middleware runs?

This middleware adds a custom header X-Custom with value 42. What will the response headers contain after a request?

FastAPI
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware

app = FastAPI()

class HeaderMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        response = await call_next(request)
        response.headers["X-Custom"] = "42"
        return response

app.add_middleware(HeaderMiddleware)

@app.get('/')
async def root():
    return {"hello": "world"}
AResponse headers include 'X-Custom': '24'
BResponse headers include 'x-custom': '42' (lowercase key)
CResponse headers do not include 'X-Custom'
DResponse headers include 'X-Custom': '42'
Attempts:
2 left
💡 Hint

Look at how the header is added to the response object.

🔧 Debug
advanced
2:00remaining
Why does this middleware cause a runtime error?

Examine this middleware code. Why does it cause a runtime error when a request is made?

FastAPI
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware

app = FastAPI()

class FaultyMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        response = call_next(request)  # Missing await
        return response

app.add_middleware(FaultyMiddleware)

@app.get('/')
async def root():
    return {"msg": "ok"}
Acall_next is a coroutine and must be awaited, missing await causes runtime error
Bdispatch method must not be async
CBaseHTTPMiddleware requires a sync dispatch method
DRequest parameter type is incorrect
Attempts:
2 left
💡 Hint

Check how call_next is called inside dispatch.

🧠 Conceptual
expert
3:00remaining
How does FastAPI middleware affect request processing order?

Given multiple middlewares added in this order: MiddlewareA, then MiddlewareB, which statement best describes the order of dispatch calls and response returns?

A<code>MiddlewareA.dispatch</code> runs first on request, then <code>MiddlewareB.dispatch</code>, response returns back through <code>MiddlewareB</code> then <code>MiddlewareA</code>
B<code>MiddlewareB.dispatch</code> runs first on request, then <code>MiddlewareA.dispatch</code>, response returns back through <code>MiddlewareA</code> then <code>MiddlewareB</code>
CBoth middlewares run their dispatch methods simultaneously
DMiddleware order does not affect dispatch call order
Attempts:
2 left
💡 Hint

Think of middleware as layers wrapping the app, like nested boxes.

Practice

(1/5)
1. What is the main purpose of creating custom middleware in FastAPI?
easy
A. To handle user authentication only
B. To define database models
C. To create HTML templates
D. To run code before and after each request is processed

Solution

  1. Step 1: Understand middleware role

    Middleware runs code around request processing, before and after the main handler.
  2. Step 2: Identify correct purpose

    Custom middleware is not for database or templates but for request/response handling.
  3. Final Answer:

    To run code before and after each request is processed -> Option D
  4. Quick Check:

    Middleware = pre/post request code [OK]
Hint: Middleware wraps requests to add extra processing [OK]
Common Mistakes:
  • Confusing middleware with database or template code
  • Thinking middleware only handles authentication
  • Believing middleware runs only after requests
2. Which method must be overridden when creating a custom middleware class in FastAPI?
easy
A. dispatch
B. execute
C. process
D. handle_request

Solution

  1. Step 1: Recall FastAPI middleware structure

    Custom middleware classes override the dispatch method to handle requests.
  2. Step 2: Match method names

    Only dispatch is the correct method name; others are invalid in FastAPI middleware.
  3. Final Answer:

    dispatch -> Option A
  4. Quick Check:

    dispatch method overrides middleware behavior [OK]
Hint: dispatch handles request and response in middleware [OK]
Common Mistakes:
  • Using incorrect method names like handle_request
  • Confusing middleware methods with route handlers
  • Forgetting to override dispatch method
3. Given this middleware code snippet, what will be printed when a request is processed?
class LogMiddleware:
    async def dispatch(self, request, call_next):
        print('Before request')
        response = await call_next(request)
        print('After request')
        return response
medium
A. Only Before request printed
B. Before request printed, then After request printed after response
C. Only After request printed
D. No output printed

Solution

  1. Step 1: Analyze dispatch method flow

    Print 'Before request' runs before calling next handler, 'After request' runs after awaiting response.
  2. Step 2: Understand async call_next behavior

    call_next processes the request and returns response; code after await runs after response is ready.
  3. Final Answer:

    Before request printed, then After request printed after response -> Option B
  4. Quick Check:

    Print before and after call_next = B [OK]
Hint: Code before await runs first, after await runs last [OK]
Common Mistakes:
  • Thinking 'After request' prints before response
  • Ignoring async await order
  • Assuming only one print runs
4. Identify the error in this custom middleware code:
class MyMiddleware:
    async def dispatch(self, request):
        response = await call_next(request)
        return response
medium
A. Response must be created manually, not awaited
B. dispatch method should not be async
C. Missing call_next parameter in dispatch method
D. Middleware class must inherit from BaseHTTPMiddleware

Solution

  1. Step 1: Check dispatch method signature

    dispatch must accept both request and call_next parameters to call next handler.
  2. Step 2: Identify missing parameter

    Code lacks call_next parameter, causing runtime error when calling call_next(request).
  3. Final Answer:

    Missing call_next parameter in dispatch method -> Option C
  4. Quick Check:

    dispatch(request, call_next) required [OK]
Hint: dispatch needs call_next argument to forward requests [OK]
Common Mistakes:
  • Omitting call_next parameter
  • Making dispatch synchronous
  • Not inheriting middleware base class (optional but recommended)
5. You want to create a middleware that adds a custom header 'X-Process-Time' showing how long the request took. Which code snippet correctly implements this?
hard
A. class TimerMiddleware: async def dispatch(self, request, call_next): start = time.time() response = await call_next(request) process_time = time.time() - start response.headers['X-Process-Time'] = str(process_time) return response
B. class TimerMiddleware: async def dispatch(self, request): start = time.time() response = await call_next(request) response.headers['X-Process-Time'] = str(time.time() - start) return response
C. class TimerMiddleware: def dispatch(self, request, call_next): start = time.time() response = call_next(request) response.headers['X-Process-Time'] = str(time.time() - start) return response
D. class TimerMiddleware: async def dispatch(self, request, call_next): response = await call_next(request) response.headers['X-Process-Time'] = time.time() return response

Solution

  1. Step 1: Check dispatch method signature and async usage

    dispatch must be async and accept request and call_next parameters.
  2. Step 2: Verify timing and header addition

    Start time before await call_next, calculate duration after, add header as string.
  3. Step 3: Identify correct code snippet

    class TimerMiddleware: async def dispatch(self, request, call_next): start = time.time() response = await call_next(request) process_time = time.time() - start response.headers['X-Process-Time'] = str(process_time) return response correctly implements timing, async, and header addition.
  4. Final Answer:

    The code snippet that correctly adds X-Process-Time header -> Option A
  5. Quick Check:

    Async dispatch with timing and header = A [OK]
Hint: Measure time before and after await call_next, add header [OK]
Common Mistakes:
  • Missing call_next parameter
  • Not awaiting call_next
  • Adding header before timing calculation
  • Using synchronous dispatch method