Тело HTTP-запроса
Этот раздел покажет, как извлекать и проверять body
с помощью Rapidy
.
Описание
HTTP тело запроса — это часть запроса, передающая данные от клиента к серверу. Оно играет ключевую роль в методах POST
, PUT
и PATCH
, которые
используются для создания, обновления и модификации ресурсов.
Например, при POST
-запросе для создания учетной записи пользователя данные передаются в теле запроса.
from pydantic import BaseModel
from rapidy.http import post, Body
class UserData(BaseModel):
username: str
password: str
@post('/')
async def handler(
user_data: UserData = Body(),
) -> ...:
Атрибуты Body
content_type
Определяет ожидаемый сервером тип данных в body
.
Подробнее про enum ContentType
можно прочитать здесь.
Rapidy
использует заданный content_type
для корректного извлечения данных.
Основные поддерживаемые типы:
application/json
application/x-www-form-urlencoded
multipart/form-data
text/*
— любые MIME-типы с текстовыми даннымиapplication/octet-stream
Если сервер ожидает формат, который Rapidy
явно не поддерживает (например, video/mpeg
), данные будут извлечены как bytes
и переданы в pydantic
-модель без обработки.
check_content_type
Определяет, нужно ли проверять заголовок Content-Type
.
- При
True
(значение по умолчанию)Rapidy
сравнит переданный заголовокContent-Type
с ожидаемымcontent_type
. Если они не совпадают, клиенту вернется ошибка:
{
"errors": [
{
"type": "ExtractError",
"loc": [
"body"
],
"msg": "Failed to extract body data: Expected Content-Type `text/plain`, got `<current_request_content_type>`"
}
]
}
json_decoder
Позволяет задать пользовательский json_decoder
для обработки JSON-данных в теле запроса.
Работает только при content_type="application/json"
.
По умолчанию Rapidy
использует json.loads
без параметров.
Эквивалентные примеры:
илиЕсли требуется кастомная обработка JSON, передайте в json_decoder
любой вызываемый объект, принимающий str
.
Ожидаемый тип данных: Callable[[str], Any]
.
Пример с пользовательским декодером:
Чтобы использовать json.loads
с параметрами или передать декодер с аргументами, воспользуйтесь functools.partial
:
import json
from functools import partial
from typing import Any, OrderedDict
from rapidy.http import post, Body
decoder = partial(json.loads, object_pairs_hook=OrderedDict)
@post('/')
async def handler(
data: Any = Body(json_decoder=decoder),
) -> ...:
Извлечение без валидации
Большинство типов Body
поддерживают извлечение данных без валидации.
Этот метод не рекомендуется.
Если валидация отключена, параметр вернет базовую структуру aiohttp
.
Подробнее об этом можно прочитать в разделе Извлечение без валидации для каждого типа body
.
Способы отключения валидации:
Явное отключение
from pydantic import BaseModel
from rapidy.http import post, Body
class BodyData(BaseModel):
...
@post('/')
async def handler(
data: BodyData = Body(validate=False),
) -> ...:
Использование Any
Отсутствие аннотации типа
Если тип не указан, по умолчанию используется Any
.
Значения по умолчанию
Большинство типов Body
поддерживают значения по умолчанию.
Если HTTP-запрос не содержит тела, параметр получит указанное значение по умолчанию (если оно задано).
Примеры использования
Указано значение по умолчанию
from pydantic import BaseModel
from rapidy.http import post, Body
class BodyData(BaseModel):
...
@post('/')
async def handler(
data: BodyData = Body('some_data'),
# or
data: BodyData = Body(default_factory=lambda: 'some_data'),
) -> ...:
Опциональное тело запроса
from pydantic import BaseModel
from rapidy.http import post, Body
class BodyData(BaseModel):
...
@post('/')
async def handler(
data: BodyData | None = Body(),
# or
data: Optional[BodyData] = Body(),
# or
data: Union[BodyData, None] = Body(),
) -> ...:
Подробнее об этом можно прочитать в разделе Значения по умолчанию для каждого типа body
.