12 KiB
Body - Множество параметров
Теперь, когда мы увидели, как использовать Path
и Query
параметры, давайте рассмотрим более продвинутые примеры обьявления тела запроса.
Обьединение Path
, Query
и параметров тела запроса
Во-первых, конечно, вы можете объединять параметры Path
, Query
и объявления тела запроса в своих функциях обработки, FastAPI автоматически определит, что с ними нужно делать.
Вы также можете объявить параметры тела запроса как необязательные, установив значение по умолчанию, равное None
:
=== "Python 3.10+"
```Python hl_lines="18-20"
{!> ../../../docs_src/body_multiple_params/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="18-20"
{!> ../../../docs_src/body_multiple_params/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="19-21"
{!> ../../../docs_src/body_multiple_params/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Заметка"
Рекомендуется использовать `Annotated` версию, если это возможно.
```Python hl_lines="17-19"
{!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Заметка"
Рекомендуется использовать версию с `Annotated`, если это возможно.
```Python hl_lines="19-21"
{!> ../../../docs_src/body_multiple_params/tutorial001.py!}
```
!!! note "Заметка"
Заметьте, что в данном случае параметр item
, который будет взят из тела запроса, необязателен. Так как было установлено значение None
по умолчанию.
Несколько параметров тела запроса
В предыдущем примере, операции пути ожидали тело запроса в формате JSON-тело с параметрами, соответствующими атрибутам Item
, например:
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
Но вы также можете объявить множество параметров тела запроса, например item
и user
:
=== "Python 3.10+"
```Python hl_lines="20"
{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!}
```
=== "Python 3.8+"
```Python hl_lines="22"
{!> ../../../docs_src/body_multiple_params/tutorial002.py!}
```
В этом случае FastAPI заметит, что в функции есть более одного параметра тела (два параметра, которые являются моделями Pydantic).
Таким образом, имена параметров будут использоваться в качестве ключей (имён полей) в теле запроса, и будет ожидаться запрос следующего формата:
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
}
}
!!! note "Внимание"
Обратите внимание, что хотя параметр item
был объявлен таким же способом, как и раньше, теперь предпологается, что он находится внутри тела с ключом item
.
FastAPI сделает автоматические преобразование из запроса, так что параметр item
получит своё конкретное содержимое, и то же самое происходит с пользователем user
.
Произойдёт проверка составных данных, и создание документации в схеме OpenAPI и автоматических документах.
Отдельные значения в теле запроса
Точно так же, как Query
и Path
используются для определения дополнительных данных для query и path параметров, FastAPI предоставляет аналогичный инструмент - Body
.
Например, расширяя предыдущую модель, вы можете решить, что вам нужен еще один ключ importance
в том же теле запроса, помимо параметров item
и user
.
Если вы объявите его без указания, какой именно объект (Path, Query, Body и .т.п.) ожидаете, то, поскольку это является простым типом данных, FastAPI будет считать, что это query-параметр.
Но вы можете указать FastAPI обрабатывать его, как ещё один ключ тела запроса, используя Body
:
=== "Python 3.10+"
```Python hl_lines="23"
{!> ../../../docs_src/body_multiple_params/tutorial003_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="23"
{!> ../../../docs_src/body_multiple_params/tutorial003_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="24"
{!> ../../../docs_src/body_multiple_params/tutorial003_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Заметка"
Рекомендуется использовать `Annotated` версию, если это возможно.
```Python hl_lines="20"
{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Заметка"
Рекомендуется использовать `Annotated` версию, если это возможно.
```Python hl_lines="22"
{!> ../../../docs_src/body_multiple_params/tutorial003.py!}
```
В этом случае, FastAPI будет ожидать тело запроса в формате:
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
},
"importance": 5
}
И всё будет работать так же - преобразование типов данных, валидация, документирование и т.д.
Множество body и query параметров
Конечно, вы также можете объявлять query-параметры в любое время, дополнительно к любым body-параметрам.
Поскольку по умолчанию, отдельные значения интерпретируются как query-параметры, вам не нужно явно добавлять Query
, вы можете просто сделать так:
q: Union[str, None] = None
Или в Python 3.10 и выше:
q: str | None = None
Например:
=== "Python 3.10+"
```Python hl_lines="27"
{!> ../../../docs_src/body_multiple_params/tutorial004_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="27"
{!> ../../../docs_src/body_multiple_params/tutorial004_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="28"
{!> ../../../docs_src/body_multiple_params/tutorial004_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Заметка"
Рекомендуется использовать `Annotated` версию, если это возможно.
```Python hl_lines="25"
{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Заметка"
Рекомендуется использовать `Annotated` версию, если это возможно.
```Python hl_lines="27"
{!> ../../../docs_src/body_multiple_params/tutorial004.py!}
```
!!! info "Информация"
Body
также имеет все те же дополнительные параметры валидации и метаданных, как у Query
,Path
и других, которые вы увидите позже.
Добавление одного body-параметра
Предположим, у вас есть только один body-параметр item
из Pydantic модели Item
.
По умолчанию, FastAPI ожидает получить тело запроса напрямую.
Но если вы хотите чтобы он ожидал JSON с ключом item
с содержимым модели внутри, также как это происходит при объявлении дополнительных body-параметров, вы можете использовать специальный параметр embed
у типа Body
:
item: Item = Body(embed=True)
так же, как в этом примере:
=== "Python 3.10+"
```Python hl_lines="17"
{!> ../../../docs_src/body_multiple_params/tutorial005_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="17"
{!> ../../../docs_src/body_multiple_params/tutorial005_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="18"
{!> ../../../docs_src/body_multiple_params/tutorial005_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Заметка"
Рекомендуется использовать `Annotated` версию, если это возможно.
```Python hl_lines="15"
{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Заметка"
Рекомендуется использовать `Annotated` версию, если это возможно.
```Python hl_lines="17"
{!> ../../../docs_src/body_multiple_params/tutorial005.py!}
```
В этом случае FastAPI будет ожидать тело запроса в формате:
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
}
вместо этого:
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
Резюме
Вы можете добавлять несколько body-параметров вашей функции операции пути, несмотря даже на то, что запрос может содержать только одно тело.
Но FastAPI справится с этим, предоставит правильные данные в вашей функции, а также сделает валидацию и документацию правильной схемы операции пути.
Вы также можете объявить отдельные значения для получения в рамках тела запроса.
И вы можете настроить FastAPI таким образом, чтобы включить тело запроса в ключ, даже если объявлен только один параметр.