# Unit 11: Multiple Parameters

## Introduction

In FastAPI, you can combine different types of request data (Path, Query, and Body) in the same function to build more versatile and dynamic endpoints. Here's a breakdown of how these components work together:

1. **Path Parameters**: These are part of the URL path and are used to capture values that are specific to the request. They are essential for identifying resources. For example, in `/items/{item_id}`, `item_id` is a path parameter.
2. **Query Parameters**: These are optional key-value pairs at the end of the URL, starting with a `?` and separated by `&`. They are used for filtering, sorting, or specifying certain aspects of the request without changing the resource path. For example, in `/items?limit=10`, `limit` is a query parameter.
3. **Request Body**: This is the data sent by the client to your API. It's typically used with POST, PUT, and PATCH requests to send the content of the item to be created or updated. The request body is usually in JSON format.

## Combine Path, Query and Body Parameters

Let's take a look at the following program:

{% code lineNumbers="true" %}

```python
from fastapi import FastAPI, Path
from typing import Annotated
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = None


@app.put("/items/{item_id}")
async def update_item(
    item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000)],
    q: str = None,
    item: Item = None,
):
    results = {"item_id": item_id}
    if q:
        results.update({"q": q})
    if item:
        results.update({"item": item})
    return results
```

{% endcode %}

To evaluate the program, there are three inputs in the request, i.e., a path parameter, a query parameter, and a request body, as shown in Fig. 1. You should note that the function `update_item()` requires a PUT method.

<figure><img src="/files/Qht8aMtM5exsQhe0DY3t" alt=""><figcaption><p>Fig. 1. An example of a mix of path, query parameters and a request body in Postman</p></figcaption></figure>

## Multiple Body Parameters

In previous program, the body request accepts an input `Item`, but you can declare multiple body parameters such as `Item`, `User`.

{% code lineNumbers="true" %}

```python
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = None

class User(BaseModel):
    username: str
    full_name: str = None

@app.put("/items/{item_id}")
async def create_item(item: Item, user: User, item_id: int):
    results = {"item_id": item_id, "item": item, "user": user}
    return item
```

{% endcode %}

The program above can be evaluated by using Postman, as shown in Fig. 2.

<figure><img src="/files/WiyhVWV5AeBoI0I3gCZ4" alt=""><figcaption><p>Fig. 2. An example of a mix of path, query parameters and a request body in Postman</p></figcaption></figure>

## Singular Values in Body

If you declare a function parameter as is, because it is a singular value, FastAPI will assume that it is a query parameter. To instruct FastAPI to treat a function parameter as another body key using `Body`.

{% code lineNumbers="true" %}

```python
from fastapi import FastAPI, Body
from typing import Annotated
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = None

@app.put("/items/{item_id}")
async def update_item(
    item_id: int,
    item: Item,
    importance: Annotated[int, Body()]
):
    results = {"item_id": item_id, "item": item, "importance": importance}
    return results
```

{% endcode %}

In the above program, the `importance` is a body request (in JSON format) instead of a query parameter. Fig. 3 shows the program evaluation in Postman.

<figure><img src="/files/AdKQ3uAiwoxVkkygi9eZ" alt=""><figcaption><p>Fig. 3. Evaluate the program in Postman</p></figcaption></figure>

## Embed a Single Body Parameter

If you only have a single `item` body parameter from a Pydantic model `Item`, as we have done in previous programs, FastAPI will then expect its body directly by default.  But if you want it to expect a JSON with a key `item` and inside of it the model contents, as it does when you declare extra body parameters, you can use the special `Body` parameter embed:

```python
item: Item = Body(embed=True)
```

Let's take a look at the following program:

{% code lineNumbers="true" %}

```python
from fastapi import FastAPI, Body, Path
from typing import Annotated
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = None


@app.put("/items/{item_id}")
async def update_item(
    item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000, embed=True)],
    q: str = None,
    item: Annotated[Item, Body(embed=True)] = None,
):
    results = {"item_id": item_id}
    if q:
        results.update({"q": q})
    if item:
        results.update({"item": item})
    return results
```

{% endcode %}

You should note that the body request to evaluate the above program in Postman in Fig. 4.

<figure><img src="/files/s5qAMze5UQ6pr0fJ6ZiP" alt=""><figcaption><p>Fig. 4. Evaluate the program in Postman</p></figcaption></figure>

***

## Summary

FastAPI allows you to combine path parameters, query parameters, and request body data in a single function. This is particularly useful when you need to operate on a specific resource and still require additional data for the operation, which may not be part of the resource's unique identifier or when you need to apply certain filters or modifications specified in the query parameters.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://fastapi-docs.duonghuuphuc.com/unit-11-multiple-parameters.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
