FastAPI Query Parameters

Learn how to work with query parameters in FastAPI to build flexible APIs

Beginner 20 min Tutorial 6 steps

Overview

Developers need to understand how to effectively use query parameters in FastAPI to create flexible APIs that can handle various filtering, sorting, and pagination options.

What You'll Learn:

  • How to declare and use basic query parameters in FastAPI
  • How to set default values and make parameters optional
  • How to implement type validation and conversion
  • How to work with multiple query parameters and advanced features
1

Understanding Query Parameters

Estimated: 3 min

Query parameters are a way to pass optional information to an API endpoint. They appear in the URL after a question mark (?) and are separated by ampersands (&). In FastAPI, you can declare query parameters by simply adding function parameters to your path operation function.

info

Query parameters are optional by default in FastAPI

tip

FastAPI automatically validates query parameters based on their type hints

main.py
from fastapi import FastAPI

app = FastAPI()

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

This example shows a basic FastAPI endpoint with a path parameter (item_id) and a query parameter (q). The query parameter is optional because it has a default value of None.

2

Creating Basic Query Parameters

Estimated: 5 min

Let's create a simple FastAPI application with query parameters. Query parameters are declared as function parameters in your path operation functions.

tip

Query parameters are automatically converted to the type specified in the function signature

info

You can test this by running the server and accessing http://127.0.0.1:8000/items/?skip=1&limit=2

main.py
from fastapi import FastAPI

app = FastAPI()

fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]

@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
    return fake_items_db[skip : skip + limit]

In this example, we have two query parameters: skip and limit. Both have default values, making them optional. FastAPI will convert the string values from the URL to the specified types (int).

3

Optional Parameters with Defaults

Estimated: 4 min

Query parameters can be made optional by providing a default value. You can also use Python's Optional type hint to make this explicit.

info

Using Optional[str] = None makes it clear that the parameter is optional

tip

You can check if an optional parameter was provided by checking if it's not None

main.py
from typing import Optional
from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Optional[str] = None):
    if q:
        return {"item_id": item_id, "q": q}
    return {"item_id": item_id}

Here, q is an optional query parameter. If it's provided in the URL, it will be included in the response. If not, the response will only include the item_id.

Quick Check

How do you make a query parameter optional in FastAPI?

4

Type Validation and Conversion

Estimated: 4 min

FastAPI automatically validates and converts query parameters based on their type hints. This includes basic types like int, float, bool, and more complex types like lists.

info

FastAPI will return a 422 Unprocessable Entity error if validation fails

tip

For boolean parameters, FastAPI accepts various values like 'true', 'True', '1', 'yes', etc.

main.py
from typing import List, Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(
    q: Optional[str] = Query(None, min_length=3, max_length=50),
    limit: int = Query(10, ge=1, le=100),
    enabled: bool = Query(True)
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    results.update({"limit": limit, "enabled": enabled})
    return results

This example shows advanced validation using the Query class. We're adding constraints like min_length, max_length for strings, and ge (greater than or equal), le (less than or equal) for numbers.

5

Multiple Query Parameters

Estimated: 4 min

You can declare as many query parameters as you need. FastAPI will handle each one according to its type and validation rules.

tip

You can use regex patterns to validate string parameters against specific patterns

info

Query parameters can be combined to create powerful filtering and sorting options

main.py
from typing import List, Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(
    q: Optional[str] = None,
    skip: int = 0,
    limit: int = 10,
    sort_by: Optional[str] = Query(None, regex="^(name|price|id)$"),
    order: Optional[str] = Query("asc", regex="^(asc|desc)$")
):
    items = [
        {"id": 1, "name": "Item 1", "price": 10.99},
        {"id": 2, "name": "Item 2", "price": 20.99},
        {"id": 3, "name": "Item 3", "price": 5.99}
    ]
    
    # Apply sorting if specified
    if sort_by:
        reverse = order == "desc"
        items.sort(key=lambda x: x[sort_by], reverse=reverse)
    
    # Apply pagination
    return items[skip : skip + limit]

This example shows multiple query parameters with different types and validation rules. We have a search term (q), pagination (skip, limit), and sorting options (sort_by, order).

6

List Query Parameters

Estimated: 5 min

Sometimes you need to accept multiple values for a single parameter. FastAPI allows you to declare query parameters that accept multiple values using List type hints.

info

To send multiple values for a parameter, repeat the parameter name in the URL: ?ids=1&ids=2&ids=3

tip

You can also use comma-separated values: ?ids=1,2,3 by customizing the Query parameter

main.py
from typing import List, Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(
    ids: Optional[List[int]] = Query(None),
    tags: Optional[List[str]] = Query(None)
):
    items = [
        {"id": 1, "name": "Item 1", "tags": ["electronics", "gadget"]},
        {"id": 2, "name": "Item 2", "tags": ["books", "education"]},
        {"id": 3, "name": "Item 3", "tags": ["electronics", "audio"]}
    ]
    
    # Filter by IDs if provided
    if ids:
        items = [item for item in items if item["id"] in ids]
    
    # Filter by tags if provided
    if tags:
        items = [item for item in items if any(tag in item["tags"] for tag in tags)]
    
    return items

This example shows how to accept multiple values for a single parameter. The ids parameter accepts multiple integers, and the tags parameter accepts multiple strings.