HTTP-ответ
Раздел описывает как можно сформировать и отправить HTTP-ответ в Rapidy
.
Описание
HTTP-ответ — это сообщение, которое сервер отправляет клиенту в ответ на его запрос.
Пример текстового HTTP-ответа (протокол HTTP/1.1)
HTTP/1.1 200 OK
Server: Nginx
Content-Type: text/html; charset=utf-8
Date: Wed, 10 Aug 2024 11:00:00 GMT
Keep-Alive: timeout=5, max=1000
Connection: Keep-Alive
Age: 3464
Date: Wed, 10 Aug 2024 11:10:00 GMT
X-Cache-Info: caching
Content-Length: 220
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN>">
(... more body data ...)
Структура HTTP-ответа
HTTP-ответ состоит из стартовой строки, заголовков и тела.
Стартовая строка
HTTP/1.1 200 OK
Стартовая строка (или строка статуса) включает:
- Версию протокола (HTTP-протокол) — HTTP/1.1
- Код состояния (числовой код, обозначающий статус запроса) — 200
- Пояснение (краткое текстовое описание кода состояния) — OK
Версии HTTP-протокола
HTTP-стандарты разрабатываются Internet Engineering Task Force (IETF) и World Wide Web Consortium (W3C), что приводит к публикации серии документов Requests for Comments (RFC).
Версия протокола | Тип HTTP-протокола | Транспортный уровень | Описание |
---|---|---|---|
HTTP/1.1 | Текстовый | TCP | Требует дожидаться ответа перед отправкой следующего запроса в рамках одного соединения. |
HTTP/2 | Бинарный | TCP | Позволяет отправлять несколько запросов одновременно без ожидания завершения предыдущих. |
HTTP/3/QUIC | Бинарный | UDP | Работает поверх UDP (использует технологию QUIC). |
Коды состояния HTTP
HTTP-коды состояния сообщают клиенту результат обработки его запроса. Они делятся на пять категорий:
Код | Описание |
---|---|
1xx | Информационные коды, не влияющие на обработку запроса. |
2xx | Успешная обработка запроса. |
3xx | Перенаправление клиента на другой ресурс. |
4xx | Ошибки на стороне клиента (например, неверный запрос или недостаток прав доступа). |
5xx | Ошибки на стороне сервера. |
Заголовки ответа
Заголовки ответа (Response Headers) уточняют детали ответа, и никак не влияют на содержимое тела.
Примеры заголовков
Категория | Пример | Описание |
---|---|---|
Server | Server: nginx | Информация о сервере, обработавшем запрос. |
Set-Cookie | Set-Cookie:UserData=SomeData123 | Cookie с информацией о пользователе, сохраняемой браузером. |
Тело ответа
Опциональная часть ответа, содержащая данные.
Сервер указывает тип передаваемых данных с помощью заголовка Content-Type
.
Тело ответа может представлять собой JSON, медиафайл, документ, текст или даже произвольный набор байтов.
Формирование HTTP-ответа
Простой ответ http-обработчика может выглядеть так:
from rapidy.http import get
@get('/')
async def handler() -> dict[str, str]:
return {'hello': 'rapidy'}
Валидация и сериализация ответа
Для валидации и сериализации ответов Rapidy
использует pydantic
.
При запуске сервера Rapidy
создает pydantic
-модель для каждого обработчика на основе аннотации возврата и использует её для валидации данных в ответе.
Можно переопределить тип для валидации или отменить создание pydantic
-модели с помощью атрибутов response_validate
и response_type
.
from rapidy.http import get
@get(
'/',
response_validate=False,
)
async def handler() -> str: # <-- `str` will be ignored
return {'hello': 'rapidy'}
Подробнее об аттрибутах ответа для http-обработчика можно прочитать здесь.
Примеры успешных ответов
@post('/')
async def handler() -> int: # <-- `int` will be used to validate
return '123' # success response --> `123`
Примеры неуспешных ответов
from rapidy.http import get
@get('/')
async def handler() -> int: # <-- `int` will be used to validate
return 'some_data' # <-- will raise err
------------------------------
Validation errors:
[{'loc': ('body',),
'msg': 'Input should be a valid integer, unable to parse string as an '
'integer',
'type': 'int_parsing'}]
Handler path: `main.py`
Handler name: `handler`
------------------------------
Продвинутый уровень управления HTTP-ответом
Для управления HTTP-ответами Rapidy
использует объект Response
.
Объект Response
может быть создан как самим Rapidy
внутри себя для формирования ответа, так и разработчиком для явного управления им.
Подробнее об объекте Response
можно прочитать здесь.
Автоматическое создание Response-объекта
Rapidy
автоматически создает Response
в следующих случаях:
В обработчике определен атрибут с любым именем и типом Response
Это даёт разработчику больше гибкости в управлении HTTP
-ответами, позволяя, например, устанавливать статус-код, cookies и другие параметры.
Подробнее о параметрах объекта Response
можно узнать здесь.
from rapidy.http import get, Response
@get('/')
async def handler(
response: Response, # <-- current response
) -> str:
some_answer: bool = ...
if some_answer:
response.set_status(200)
return 'ok'
response.set_status(500)
return 'not ok'
Также можно вернуть этот же Response
объект.
from rapidy.http import get, Response
@get('/')
async def handler(response: Response) -> Response:
return response
Обработчик возвращает python
объект
from rapidy.http import get
@get('/')
async def handler() -> dict[str, str]:
return {'hello': 'rapidy'}
Если в обработчике уже определён атрибут с типом Response
, а сам обработчик возвращает python
-объект, то новый экземпляр Response
создаваться не будет.
Обработчик возвращает Response-объект
Rapidy
позволяет разработчику самостоятельно управлять и формировать Response
объект.
from rapidy.http import get, Response
@get('/')
async def handler() -> Response:
return Response(status=201)
При прямом управлении ответом атрибуты веб-обработчика игнорируются
Если Response
объект был проброшел в аттрибут, а разработчик отдает новый Response
то проброшенный Response
игнорируется.
При прямом управлении ответом валидация pydantic
не будет работать.
Обработчик возвращает None
Если обработчик Rapidy
ничего не возвращает, то по умолчанию Rapidy
вернет текущий Response
объект.
Если вы изменили запрос и ничего не вернули из обработчика, то будет отдан именно этот измененный запрос!
from rapidy.http import get, Response
@get('/')
async def handler(response: Response) -> None:
response.text = 'hello rapidy!'
# success response --> `hello rapidy!`
Атрибуты http-обработчиков
Атрибуты ответа веб-обработчика используются для управления формированием ответа при возврате любого python
-объекта из обработчика.
Код состояния по умолчанию
Для управления кодом состояния по умолчанию вы можете определить атрибут status_code
.
from http import HTTPStatus
from rapidy.http import get
@get(
'/',
status_code=201,
)
async def handler() -> ...:
...
@get(
'/',
status_code=HTTPStatus.CREATED,
)
async def handler() -> ...:
...
Об остальных аттрибутах можно прочитать здесь.
Rapidy позволяет управлять атрибутами во всех типах обработчиков, включая те, что оформлены в стиле aiohttp.