# 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" !!! Заметка Рекомендуется использовать `Annotated` версию, если это возможно. ```Python hl_lines="17-19" {!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!} ``` === "Python 3.8+ non-Annotated" !!! Заметка Рекомендуется использовать версию с `Annotated`, если это возможно. ```Python hl_lines="19-21" {!> ../../../docs_src/body_multiple_params/tutorial001.py!} ``` !!! Заметка Заметьте, что в данном случае параметр `item`, который будет взят из тела запроса, необязателен. Так как было установлено значение `None` по умолчанию. ## Несколько параметров тела запроса В предыдущем примере, *операции пути* ожидали тело запроса в формате JSON-тело с параметрами, соответствующими атрибутам `Item`, например: ```JSON { "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). Таким образом, имена параметров будут использоваться в качестве ключей (имён полей) в теле запроса, и будет ожидаться запрос следующего формата: ```JSON { "item": { "name": "Foo", "description": "The pretender", "price": 42.0, "tax": 3.2 }, "user": { "username": "dave", "full_name": "Dave Grohl" } } ``` !!! Внимание Обратите внимание, что хотя параметр `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" !!! Заметка Рекомендуется использовать `Annotated` версию, если это возможно. ```Python hl_lines="20" {!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!} ``` === "Python 3.8+ non-Annotated" !!! Заметка Рекомендуется использовать `Annotated` версию, если это возможно. ```Python hl_lines="22" {!> ../../../docs_src/body_multiple_params/tutorial003.py!} ``` В этом случае, **FastAPI** будет ожидать тело запроса в формате: ```JSON { "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`, вы можете просто сделать так: ```Python q: Union[str, None] = None ``` Или в Python 3.10 и выше: ```Python 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" !!! Заметка Рекомендуется использовать `Annotated` версию, если это возможно. ```Python hl_lines="25" {!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!} ``` === "Python 3.8+ non-Annotated" !!! Заметка Рекомендуется использовать `Annotated` версию, если это возможно. ```Python hl_lines="27" {!> ../../../docs_src/body_multiple_params/tutorial004.py!} ``` !!! Информация `Body` также имеет все те же дополнительные параметры валидации и метаданных, как у `Query`,`Path` и других, которые вы увидите позже. ## Добавление одного body-параметра Предположим, у вас есть только один body-параметр `item` из Pydantic модели `Item`. По умолчанию, **FastAPI** ожидает получить тело запроса напрямую. Но если вы хотите чтобы он ожидал JSON с ключом `item` с содержимым модели внутри, также как это происходит при объявлении дополнительных body-параметров, вы можете использовать специальный параметр `embed` у типа `Body`: ```Python 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" !!! Заметка Рекомендуется использовать `Annotated` версию, если это возможно. ```Python hl_lines="15" {!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!} ``` === "Python 3.8+ non-Annotated" !!! Заметка Рекомендуется использовать `Annotated` версию, если это возможно. ```Python hl_lines="17" {!> ../../../docs_src/body_multiple_params/tutorial005.py!} ``` В этом случае **FastAPI** будет ожидать тело запроса в формате: ```JSON hl_lines="2" { "item": { "name": "Foo", "description": "The pretender", "price": 42.0, "tax": 3.2 } } ``` вместо этого: ```JSON { "name": "Foo", "description": "The pretender", "price": 42.0, "tax": 3.2 } ``` ## Резюме Вы можете добавлять несколько body-параметров вашей *функции операции пути*, несмотря даже на то, что запрос может содержать только одно тело. Но **FastAPI** справится с этим, предоставит правильные данные в вашей функции, а также сделает валидацию и документацию правильной схемы *операции пути*. Вы также можете объявить отдельные значения для получения в рамках тела запроса. И вы можете настроить **FastAPI** таким образом, чтобы включить тело запроса в ключ, даже если объявлен только один параметр.