Introduction: Why Path and Query Parameters?
1. Introduction: Why Path and Query Parameters?
Welcome to Lesson 13 of our Python and FastAPI beginner course. In the previous lesson, you built your first API endpoint that returned a simple "Hello, World!" message. That was a great start, but real-world APIs need to be dynamic. They need to respond differently based on input from the client. This is where path parameters and query parameters come in.
Imagine you are building a library API. You don't want a separate endpoint for every single book. Instead, you want one endpoint like /books/123 that returns the book with ID 123. The 123 part is a path parameter. It's a variable part of the URL path that identifies a specific resource.
Now, what if you want to search for books by author or filter by year? You don't want to create a new path for every filter. Instead, you add query parameters to the URL, like /books?author=Tolkien&year=1954. These are key-value pairs that come after a ? in the URL.
In this chapter, you will learn:
- What path parameters are and how to use them in FastAPI.
- What query parameters are and how to handle them.
- How to combine both in a single endpoint.
- Common mistakes beginners make and how to avoid them.
By the end of this lesson, you will be able to create dynamic endpoints that accept input from the user, making your API much more powerful and flexible.
2. Path Parameters: Dynamic URL Parts
A path parameter is a variable part of the URL path. In FastAPI, you define it by placing a placeholder inside curly braces {} in the path decorator. FastAPI automatically extracts the value from the URL and passes it to your function as an argument.
Let's start with a simple example. We will create an endpoint that greets a user by name.
2.1. Basic Path Parameter Example
Create a new file called main.py and write the following code:
from fastapi import FastAPI
app = FastAPI()
@app.get("/greet/{name}")
async def greet_user(name: str):
return {"message": f"Hello, {name}!"}
Explanation:
@app.get("/greet/{name}"): The{name}is a path parameter. When a user visits/greet/Alice, FastAPI capturesAliceas the value ofname.async def greet_user(name: str):: The function receivesnameas a parameter. We also specify the type asstr. FastAPI uses this type hint for validation and automatic documentation.- The function returns a JSON response with a personalized greeting.
Run the server with uvicorn main:app --reload and visit http://127.0.0.1:8000/greet/Alice in your browser. You should see: {"message":"Hello, Alice!"}.
2.2. Path Parameters with Different Types
Path parameters are not limited to strings. You can use integers, floats, or any other valid Python type. FastAPI will automatically convert the string from the URL to the specified type and raise a validation error if the conversion fails.
Here is an example that returns a user by their ID (an integer):
@app.get("/users/{user_id}")
async def get_user(user_id: int):
return {"user_id": user_id, "name": f"User_{user_id}"}
If you visit /users/42, you get {"user_id":42,"name":"User_42"}. If you visit /users/abc, FastAPI will return a 422 validation error because abc cannot be converted to an integer.
2.3. Order Matters: Fixed Paths vs. Path Parameters
When you have both fixed paths and path parameters, FastAPI matches routes in the order they are defined. Always put fixed paths before parameterized ones to avoid conflicts.
@app.get("/users/me")
async def get_current_user():
return {"user": "current user"}
@app.get("/users/{user_id}")
async def get_user(user_id: int):
return {"user_id": user_id}
If you reversed the order, /users/me would never be reached because FastAPI would interpret me as a path parameter.
3. Query Parameters: Filtering and Optional Data
Query parameters are key-value pairs that appear after a ? in the URL, separated by &. They are typically used for filtering, sorting, or providing optional data. In FastAPI, any function parameter that is not a path parameter is automatically treated as a query parameter.
3.1. Basic Query Parameter Example
Let's create an endpoint that searches for items. The query parameter q will be optional.
@app.get("/items/")
async def search_items(q: str = None):
if q:
return {"query": q, "results": [f"Item matching {q}"]}
return {"query": None, "results": []}
Explanation:
q: str = None: The parameterqis optional. If the user does not provide it, it defaults toNone.- Visit
/items/?q=bookto see results. Visit/items/to see an empty list.
3.2. Multiple Query Parameters
You can have as many query parameters as you need. They are automatically parsed from the URL.
@app.get("/products/")
async def list_products(category: str = None, min_price: float = 0, max_price: float = 1000):
return {
"category": category,
"min_price": min_price,
"max_price": max_price,
"message": f"Filtering products in category '{category}' between {min_price} and {max_price}"
}
Visit /products/?category=electronics&min_price=100&max_price=500 to see the filter applied.
3.3. Required Query Parameters
If a query parameter does not have a default value, it becomes required. FastAPI will return an error if it is missing.
@app.get("/search/")
async def search(query: str):
return {"query": query, "results": [f"Result for {query}"]}
Visiting /search/ without ?query=something will result in a 422 validation error.
4. Combining Path and Query Parameters
You can mix both types in a single endpoint. Path parameters are used for required resource identifiers, while query parameters handle optional filters or options.
@app.get("/users/{user_id}/items/")
async def get_user_items(user_id: int, limit: int = 10, offset: int = 0):
return {
"user_id": user_id,
"limit": limit,
"offset": offset,
"items": [f"Item {i}" for i in range(offset, offset + limit)]
}
Visit /users/42/items/?limit=5&offset=10 to get items 10 through 14 for user 42.
5. Common Mistakes and How to Avoid Them
- Mistake 1: Forgetting the type hint. Without a type hint, FastAPI treats the parameter as a string. Always specify the type for automatic validation.
- Mistake 2: Confusing path and query parameters. Path parameters are part of the URL path (e.g.,
/users/123). Query parameters come after?(e.g.,/users?age=25). - Mistake 3: Overlapping routes. If you have
/users/{user_id}and/users/me, define the fixed route first. - Mistake 4: Not handling optional parameters. Always provide a default value (
Noneor a sensible default) for optional query parameters.
6. Practice Task
Now it's your turn. Create a new FastAPI application with the following endpoints:
- GET /books/{book_id}: Accept a path parameter
book_id(integer) and return a dictionary with the book ID and a placeholder title like"Book {book_id}". - GET /books/: Accept two optional query parameters:
author(string) andyear(integer). Return a dictionary showing the applied filters. - GET /books/{book_id}/reviews/: Accept a path parameter
book_idand an optional query parametermin_rating(float, default 0). Return a dictionary with the book ID and the minimum rating.
Test all endpoints using your browser or Swagger UI at /docs. Make sure to handle type validation and optional parameters correctly.
In the next lesson, we will learn about Pydantic models, which will help us structure our data more formally. Keep practicing!

Loading ratings...