StackScholar
  • System Design Interview Preparation

    Beginner to advanced, with interactive simulators and full design case studies.

  • Python Full-Stack Interview Preparation

    Master backend + frontend questions with real-world cases.

  • AI/ML Engineer Interview Preparation

    ML, deep learning, LLMs, RAG, MLOps and system design - with mock interviews.

Rapid Review CSnewDSA VisualizerReviewBlog
Search⌘K
System Design Interview PreparationPython Full-Stack Interview PreparationAI/ML Engineer Interview Preparation
Rapid Review CSnewDSA VisualizerReviewBlog
CurriculumAll questionsFlashcardsGlossaryVisualizersDSA Visualizer

Navigate by Range

  • Q&A Python-1-5
  • Q&A Python-6-10
  • Q&A Python-11-15
  • Q&A Python-16-20
  • Q&A Python-21-25
  • Q&A Python-26-30
  • Q&A Python-31-35
  • Q&A Python-36-40
  • Q&A Python-41-45
  • Q&A Python-46-50
  • Q&A Python-51-55
  • Q&A Python-56-60
  • Q&A Python-61-65
  • Q&A Python-66-70
  • Q&A Python-71-75
  • Q&A Python-76-80
  • Q&A Python-81-85
  • Q&A Python-86-90
  • Q&A DB-MySQL-1-5
  • Q&A DB-MySQL-6-10
  • Q&A DB-MySQL-11-15
  • Q&A DB-MySQL-16-20
  • Q&A DB-MySQL-21-25
  • Q&A DB-MySQL-26-30
  • Q&A DB-MySQL-31-35
  • Q&A DB-MySQL-36-40
  • Q&A DB-MySQL-41-45
  • Q&A DB-MySQL-46-50
  • Q&A Django-1-5
  • Q&A Django-6-10
  • Q&A Django-11-15
  • Q&A Django-16-20
  • Q&A Django-21-25
  • Q&A Django-26-30
  • Q&A Django-31-35
  • Q&A Django-36-40
  • Q&A Django-41-45
  • Q&A Django-46-50
  • Q&A FastAPI-01-05
  • Q&A FastAPI-06-10
  • Q&A FastAPI-11-15
  • Q&A FastAPI-16-20
  • Q&A FastAPI-21-25
  • Q&A FastAPI-26-30
  • Q&A FastAPI-36-40
  • Q&A FastAPI-41-45
  • Q&A FastAPI-31-35
  • Q&A FastAPI-46-50
  • Q&A FastAPI-51-55
  • Q&A FastAPI-56-60
  • Q&A FastAPI-61-65
  • Q&A HTML-01-05
  • Q&A HTML-06-10
  • Q&A HTML-11-15
  • Q&A HTML-16-20
  • Q&A CSS-01-05
  • Q&A CSS-06-10
  • Q&A CSS-11-15
  • Q&A CSS-16-20
  • Q&A JavaScript-1-5
  • Q&A JavaScript-6-10
  • Q&A JavaScript-11-15
  • Q&A JavaScript-16-20
  • Q&A JavaScript-21-25
  • Q&A JavaScript-26-30
  • Q&A JavaScript-31-35
  • Q&A JavaScript-36-40
  • Q&A JavaScript-41-45
  • Q&A JavaScript-46-50
  • Q&A React-1-5
  • Q&A React-6-10
  • Q&A React-11-15
  • Q&A React-16-20
  • Q&A React-21-25
Loading…

Navigate by Range

  • Q&A Python-1-5
  • Q&A Python-6-10
  • Q&A Python-11-15
  • Q&A Python-16-20
  • Q&A Python-21-25
  • Q&A Python-26-30
  • Q&A Python-31-35
  • Q&A Python-36-40
  • Q&A Python-41-45
  • Q&A Python-46-50
  • Q&A Python-51-55
  • Q&A Python-56-60
  • Q&A Python-61-65
  • Q&A Python-66-70
  • Q&A Python-71-75
  • Q&A Python-76-80
  • Q&A Python-81-85
  • Q&A Python-86-90
  • Q&A DB-MySQL-1-5
  • Q&A DB-MySQL-6-10
  • Q&A DB-MySQL-11-15
  • Q&A DB-MySQL-16-20
  • Q&A DB-MySQL-21-25
  • Q&A DB-MySQL-26-30
  • Q&A DB-MySQL-31-35
  • Q&A DB-MySQL-36-40
  • Q&A DB-MySQL-41-45
  • Q&A DB-MySQL-46-50
  • Q&A Django-1-5
  • Q&A Django-6-10
  • Q&A Django-11-15
  • Q&A Django-16-20
  • Q&A Django-21-25
  • Q&A Django-26-30
  • Q&A Django-31-35
  • Q&A Django-36-40
  • Q&A Django-41-45
  • Q&A Django-46-50
  • Q&A FastAPI-01-05
  • Q&A FastAPI-06-10
  • Q&A FastAPI-11-15
  • Q&A FastAPI-16-20
  • Q&A FastAPI-21-25
  • Q&A FastAPI-26-30
  • Q&A FastAPI-36-40
  • Q&A FastAPI-41-45
  • Q&A FastAPI-31-35
  • Q&A FastAPI-46-50
  • Q&A FastAPI-51-55
  • Q&A FastAPI-56-60
  • Q&A FastAPI-61-65
  • Q&A HTML-01-05
  • Q&A HTML-06-10
  • Q&A HTML-11-15
  • Q&A HTML-16-20
  • Q&A CSS-01-05
  • Q&A CSS-06-10
  • Q&A CSS-11-15
  • Q&A CSS-16-20
  • Q&A JavaScript-1-5
  • Q&A JavaScript-6-10
  • Q&A JavaScript-11-15
  • Q&A JavaScript-16-20
  • Q&A JavaScript-21-25
  • Q&A JavaScript-26-30
  • Q&A JavaScript-31-35
  • Q&A JavaScript-36-40
  • Q&A JavaScript-41-45
  • Q&A JavaScript-46-50
  • Q&A React-1-5
  • Q&A React-6-10
  • Q&A React-11-15
  • Q&A React-16-20
  • Q&A React-21-25
StackScholar

StackScholar is your go-to destination for exploring technology from every angle - from bit to supercomputer.

Quick Links

  • Home
  • Search
  • Daily Review
  • Blog
  • About
  • Contact
  • Privacy Policy

DSA Visualizer

  • DSA Visualizer
  • Sorting Algorithms
  • Binary Search Tree
  • Dijkstra's Algorithm
  • A* Pathfinding
  • Dynamic Programming

Rapid Review CS

  • Rapid Review CS
  • Operating Systems
  • DBMS
  • Computer Networks
  • Data Structures & Algorithms
  • Computer Architecture

Interview Preparation

  • System Design Interview
  • System Design Toolkit
  • System Design Patterns
  • Python Full-Stack Interview
  • AI/ML Engineer Interview
  • ML Mock Interview
  • AI/ML Glossary

Get new lessons and visualizers in your inbox

Occasional email when something substantial ships. No spam, unsubscribe anytime.

© 2026 StackScholar. All rights reserved.

FastAPI Interview Questions 16-20 (Dependency Injection, Background Tasks, & Project Structure)

Welcome back! You have mastered the basics of validation and models. Now, we move into the territory of professional software engineering. Writing a "Hello World" app is easy, but how do you write an app that has 50 endpoints, connects to a database, and sends emails without freezing the server?

In this lesson, we cover FastAPI's superpower: Dependency Injection. We will also look at how to run tasks in the background and how to structure your code so it doesn't turn into one giant, unreadable file.

16. What are dependency injections (Depends) in FastAPI?

Dependency Injection (DI) is a design pattern where a function "declares" what it needs (dependencies) to work, and the framework provides those dependencies automatically. In FastAPI, this is handled using the Depends class.

Analogy: The Chef and the Prep Cook
Imagine a Chef (your path operation function) who needs chopped onions. The Chef doesn't stop cooking to chop onions. They simply ask for them. A Prep Cook (the dependency) chops the onions and hands them over. The Chef doesn't care how they were chopped, just that they are ready.

Why use it?

  • Code Reuse: Write logic (like verifying a token) once, reuse it everywhere.
  • Testing: You can easily swap a real database connection for a fake one during tests.
  • Cleaner Code: Your path operations focus on logic, not setup.

Interview note - why Annotated, not a default value: Older tutorials write db: Session = Depends(get_db). That works, but it burns the parameter's default slot on framework metadata, so you cannot give the parameter a real default, and type checkers see the default as a Depends object rather than a Session. Putting it in Annotated[Session, Depends(get_db)] keeps the type honest, frees the default slot, and lets you alias the whole thing (DbSession = Annotated[Session, Depends(get_db)]) and reuse it across every route. This has been the style FastAPI's own documentation recommends since 0.95, and it is what interviewers expect to see now.

from typing import Annotated
from fastapi import FastAPI, Depends

app = FastAPI()

# 1. Define the dependency
# This function runs BEFORE the path operation
def common_parameters(q: str = None, skip: int = 0, limit: int = 100):
    return {"q": q, "skip": skip, "limit": limit}

# 2. Inject the dependency
@app.get("/items/")
def read_items(commons: Annotated[dict, Depends(common_parameters)]):
    # 'commons' contains the result of the function above
    return commons

@app.get("/users/")
def read_users(commons: Annotated[dict, Depends(common_parameters)]):
    # We reused the logic!
    return commons

17. How do you use Dependency Injection for DB sessions?

This is the most common use case for Depends. You need a database session for a request, and you mustclose it after the request is finished, even if an error occurs.

FastAPI solves this elegantly using a generator function with the yield keyword.

  • Code before yield: Runs before the request starts (connect to DB).
  • yield: Pauses execution and hands the session to the route.
  • Code after yield: Runs after the response is sent (close DB).
# database.py (mock setup)
from typing import Annotated
from sqlalchemy.orm import Session

# This is our dependency function
def get_db():
    db = SessionLocal() # Create session
    try:
        yield db        # Send session to the route
    finally:
        db.close()      # Clean up afterwards

# main.py
from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session

app = FastAPI()

@app.post("/users/")
def create_user(db: Annotated[Session, Depends(get_db)]):
    # Use the 'db' session here
    # No need to worry about closing it!
    return {"message": "User created"}

18. Explain FastAPI background tasks.

Sometimes you need to perform a slow action (like sending an email or processing a file) without making the user wait. You want to return a "Success" response immediately and continue working in the background.

FastAPI provides BackgroundTasks for this purpose. It is lighter than using a full task queue like Celery, perfect for small jobs.

from fastapi import FastAPI, BackgroundTasks

app = FastAPI()

# A simple function to simulate work
def write_log(message: str):
    with open("log.txt", "a") as log:
        log.write(message + "
")

@app.post("/send-notification/{email}")
def send_notification(email: str, background_tasks: BackgroundTasks):
    # 1. Add the task to the queue
    background_tasks.add_task(write_log, f"Notification sent to {email}")
    
    # 2. Return response immediately
    # The 'write_log' function runs AFTER this return
    return {"message": "Notification sent in the background"}

Interview Tip: Be clear that for heavy, CPU-intensive tasks (like video processing), you should still use Celery or RQ. FastAPI background tasks run in the same event loop as your application.

19. What are FastAPI routers and why are they used?

As your application grows, putting all endpoints into a single main.pyfile becomes unmanageable. APIRouter allows you to split your application into multiple smaller files, each handling a specific domain (like users, items, or login).

Analogy: Departments in a Company
main.py is the CEO. It shouldn't micromanage every task. Instead, it delegates to departments (Routers). There is a "Users Department" and an "Items Department". The CEO just connects them all together.

# users.py
from fastapi import APIRouter

router = APIRouter()

@router.get("/users/", tags=["users"])
def read_users():
    return [{"username": "Rick"}, {"username": "Morty"}]

# main.py
from fastapi import FastAPI
from .users import router as users_router

app = FastAPI()

# Connect the router to the main app
app.include_router(users_router)

20. How do you organize large FastAPI projects using APIRouter?

This is a system design question regarding code structure. A standard production-grade FastAPI structure separates concerns into Models (DB), Schemas (Pydantic), Routers (Endpoints), and CRUD (Logic).

Here is the recommended directory structure:

app/
├── main.py            # The entry point (initializes FastAPI)
├── dependencies.py    # reusable dependencies (get_db, get_current_user)
├── routers/           # Folder for API endpoints
│   ├── __init__.py
│   ├── users.py       # router for /users
│   └── items.py       # router for /items
├── internal/          # Internal admin logic
│   └── admin.py
├── models.py          # SQLAlchemy database models
├── schemas.py         # Pydantic models (request/response)
└── crud.py            # Functions that interact with the DB

In your main.py, you would gather everything like this:

# app/main.py
from fastapi import FastAPI
from .routers import users, items
from .internal import admin

app = FastAPI()

app.include_router(users.router)
app.include_router(items.router)
app.include_router(
    admin.router,
    prefix="/admin",
    tags=["admin"],
    responses={418: {"description": "I'm a teapot"}},
)

Check your understanding

2 questions · no sign-up, nothing stored

0/2 answered
Question 1

1.Why is Annotated[Session, Depends(get_db)] preferred over a default value?

Question 2

2.Why does a database-session dependency use yield rather than return?

0 / 74 ranges

Progress is stored in this browser only - no sign-up, nothing sent anywhere.

PreviousNext