tezvyn:

Purpose of await next(request) in FastAPI middleware and timing effects

AI-drafted, machine-checkedSource: fastapi.tiangolo.combeginner

Tests ASGI middleware lifecycle. await next(request) forwards the request downstream to the endpoint and returns the response. Pre-call code touches the request; post-call code touches the response.

WHAT THIS TESTS: This question probes whether you understand that FastAPI middleware wraps the entire request-response lifecycle, not just the pre-request phase. It reveals if you know that ASGI middleware forms a nested stack where control flows down through each layer to the endpoint and then back up through the same layers in reverse. The interviewer wants to see that you view middleware as an onion rather than a linear filter.

A GOOD ANSWER COVERS: First, define await next(request) as the explicit handoff that passes the request object to downstream middleware and ultimately the path operation function, then awaits and returns the response object. Second, explain that code before the call runs during request ingress: you can inspect or mutate request headers, enforce authentication, reject bad requests, or start a timer. Third, explain that code after the call runs during response egress: you can add CORS headers, log status codes, inject response headers, or measure total latency because the response object is now populated. Fourth, mention that omitting the call breaks the chain entirely, so the endpoint never executes and no response is generated, effectively short-circuiting the application.

COMMON WRONG ANSWERS: A major red flag is saying the call is optional or that post-call code still runs after the endpoint without it. Another is claiming both code blocks execute before the path operation. Some candidates confuse middleware with dependencies, stating that middleware only validates requests and cannot touch responses. Saying you can freely modify the response body before next without mentioning streaming or memory implications is also suspect. Additionally, asserting that exceptions after next cannot be caught inside the same middleware function shows a misunderstanding of async stack unwinding.

LIKELY FOLLOW-UPS: An interviewer might ask how multiple middleware layers interact, which follows an onion model where the first registered middleware is the outermost layer and the last is innermost. They might ask how to measure request latency accurately, which requires recording a timestamp before next and calculating the delta after it returns. They could also ask what happens if an exception is raised before versus after the call, or how dependencies with yield interact with middleware timing since exit code runs after middleware completes.

ONE CONCRETE EXAMPLE: Imagine a logging middleware. Before await next(request), you log the HTTP method and URL and store a start time in a local variable. After the call, you access response.status_code and compute elapsed = time.time() - start_time, then write a structured log line containing both request and response details. If you placed the elapsed calculation before next, you would log approximately zero milliseconds because the endpoint has not yet run. If you forgot next entirely, the client would hang indefinitely because the request never reaches a path operation.

Read the original → fastapi.tiangolo.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.