tezvyn:

Use startup events to initialize a database pool and inject it

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

This tests FastAPI lifespan hooks and dependency injection for shared state. A strong answer creates the pool in an async startup handler, stores it on app.state, and accesses it via a dependency in routes. A red flag is creating a fresh pool per request.

WHAT THIS TESTS: This question checks two things: whether you know how to run one-time initialization code before FastAPI accepts traffic, and whether you can expose that initialized resource to request handlers without tight coupling or global variables. Interviewers want to see that you understand the difference between application lifespan and request scope, and that you prefer dependency injection over hard-coded state access.

A GOOD ANSWER COVERS: First, mention that FastAPI provides startup events (or the modern lifespan context manager) that run once before the app begins serving requests. Second, explain that the connection pool should be created inside that startup handler and attached to the application instance, typically via app.state. Third, describe the pattern for making it available to path operations: either a dependency function that returns request.app.state.pool, or directly accepting Request and reading from it. Fourth, note that a shutdown event should close the pool cleanly to avoid leaked connections.

COMMON WRONG ANSWERS: A major red flag is creating the pool inside the route handler or inside a dependency that runs on every request; this defeats the purpose of pooling and adds massive latency. Another mistake is using a module-level global variable created at import time, which makes testing difficult and hides lifecycle control from the framework. Some candidates also forget to handle shutdown, leaving open sockets and database connections dangling when the process restarts.

LIKELY FOLLOW-UPS: The interviewer might ask how you would test this setup, which usually involves overriding the dependency that provides the pool or using TestClient with lifespan startup events. They could also ask about the newer lifespan async context manager introduced in FastAPI, which replaces separate startup and shutdown events and is the recommended modern approach. You might also be asked how to handle multiple database backends or how to retry initialization if the database is temporarily unavailable at startup.

ONE CONCRETE EXAMPLE: Imagine an asyncpg pool. In your startup event, you write app.state.pool = await asyncpg.create_pool(dsn). Then you define a dependency async def get_pool(request: Request): return request.app.state.pool. In your route, you write async def read_items(pool: asyncpg.Pool = Depends(get_pool)): and use pool.acquire() inside the handler. For shutdown, you add an event that calls await app.state.pool.close(). This keeps initialization logic out of your business code and makes the pool trivial to mock during unit tests.

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.