Тело 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/jsonapplication/x-www-form-urlencodedmultipart/form-datatext/*— любые 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.