FastAPI Routing


What is routing in FastAPI?

Routing in FastAPI refers to defining the URL paths (endpoints) that your application will respond to. Each route corresponds to a specific URL pattern and HTTP method (GET, POST, etc.), and it tells the FastAPI application what to do when a request is made to that URL. Routing allows you to organize your application's URLs and connect them to Python functions that handle the requests.


How do you define a basic route in FastAPI?

To define a route in FastAPI, you use decorators like @app.get(), @app.post(), @app.put(), etc., to specify the HTTP method and the path. Inside the route handler function, you can return a response, typically a dictionary that FastAPI converts to JSON.

Example of defining a basic route:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello, World!"}

In this example, the route / responds to HTTP GET requests by returning a JSON object {"message": "Hello, World!"}.


What are path parameters in FastAPI routing?

Path parameters in FastAPI are dynamic parts of the URL that are used to capture variable data from the URL. You define them inside curly braces {}, and they are passed as arguments to the route handler function.

Example of using path parameters:

@app.get("/items/{item_id}")
def read_item(item_id: int):
    return {"item_id": item_id}

In this example, {item_id} is a path parameter, and when the URL /items/5 is accessed, the value 5 is passed to the function as item_id.


What are query parameters in FastAPI routing?

Query parameters are key-value pairs sent in the URL after the ? symbol. They are optional and typically used for filtering, sorting, or pagination. You define query parameters by adding them as function parameters, with optional default values.

Example of using query parameters:

@app.get("/items/")
def read_items(skip: int = 0, limit: int = 10):
    return {"skip": skip, "limit": limit}

In this example, the route /items/ accepts two optional query parameters: skip and limit. You can access the endpoint like /items/?skip=0&limit=10 to pass values for the parameters.


How do you handle POST requests in FastAPI routing?

POST requests are used to submit data to the server, such as creating new resources. In FastAPI, you define a POST route using the @app.post() decorator and handle the incoming data using request bodies, typically defined with Pydantic models.

Example of handling POST requests:

from pydantic import BaseModel

class Item(BaseModel):
    name: str
    price: float

@app.post("/items/")
def create_item(item: Item):
    return {"name": item.name, "price": item.price}

In this example, a POST request to /items/ expects a JSON body with fields name and price. The Pydantic model Item is used to validate the request body.


How do you use path and query parameters together in FastAPI?

FastAPI allows you to combine both path parameters and query parameters in the same route. Path parameters are required, while query parameters are optional and can have default values.

Example of using path and query parameters together:

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

In this example, item_id is a required path parameter, and q is an optional query parameter. You can access the route as /items/5?q=search.


How do you organize multiple routes in FastAPI?

FastAPI allows you to organize your routes into multiple files or modules to keep your codebase clean and manageable. You can use FastAPI's APIRouter to group related routes and include them in the main application.

Example of organizing routes using APIRouter:

from fastapi import APIRouter

router = APIRouter()

@router.get("/users/")
def read_users():
    return [{"name": "John"}, {"name": "Jane"}]

@router.get("/users/{user_id}")
def read_user(user_id: int):
    return {"user_id": user_id}

In this example, routes related to users are defined in the router object. You can include this router in your main application using app.include_router():

from fastapi import FastAPI
from .routers import users

app = FastAPI()

app.include_router(users.router)

This helps you organize your routes based on functionality (e.g., users, items, etc.), making the codebase more modular and maintainable.


How do you handle route dependencies in FastAPI?

FastAPI allows you to use dependencies with routes to ensure certain functionality is applied to multiple routes, such as authentication, validation, or preprocessing of data. You can define dependencies at the route level or globally using the Depends function.

Example of using route dependencies:

from fastapi import Depends

def verify_token(token: str):
    if token != "valid_token":
        raise HTTPException(status_code=400, detail="Invalid token")

@app.get("/protected/", dependencies=[Depends(verify_token)])
def read_protected():
    return {"message": "This is a protected route"}

In this example, the verify_token function is used as a dependency for the /protected/ route. If the token is invalid, an exception is raised, and the route is protected from unauthorized access.


How do you handle default responses in FastAPI routing?

FastAPI allows you to define default responses for your routes. You can specify the default status code, headers, and body that should be returned if no other conditions are met. This is useful for returning specific responses for different HTTP status codes.

Example of handling default responses:

from fastapi import Response

@app.get("/default/")
def read_with_default_response():
    return Response(content="This is a default response", media_type="text/plain", status_code=200)

In this example, the route /default/ returns a plain text response with a custom message, and the status_code is explicitly set to 200 OK.


How do you define global dependencies for FastAPI routes?

In FastAPI, you can define global dependencies that apply to all routes in your application. Global dependencies ensure that certain logic, such as authentication or validation, is applied to every request.

Example of defining global dependencies:

from fastapi import FastAPI, Depends

app = FastAPI(dependencies=[Depends(verify_token)])

@app.get("/items/")
def read_items():
    return {"message": "All items are protected by the token check"}

In this example, the verify_token function is used as a global dependency, meaning that every route in the application will require a valid token for access.

Ads