## Обзор {#overview}

**Request** — это один HTTP-запрос, полученный Adal Server. Каждый принятый вебхук становится отдельным Request, который можно изучить в [разделе Requests](https://dashboard.adal.cloud/requests) и проследить через настроенные Destinations.

```text
Внешний сервис → Adal Server → Request → Deliveries → Destinations
```

Adal сохраняет полученные HTTP-метод, URI, путь, строку запроса, заголовки и тело без скрытого преобразования содержимого. Request описывает, что получил Server; **Delivery** отслеживает отправку этого Request в один Destination. У одного Request может быть несколько независимых Deliveries с разными результатами.

> **Важно:** Request подтверждает, что Adal принял вебхук. Успешный Delivery подтверждает, что Adal получил ожидаемый HTTP-ответ от Destination. Ни одно из этих событий не доказывает, что Destination завершил бизнес-операцию.

## Жизненный цикл Request {#lifecycle}

1. Внешний сервис отправляет HTTP-запрос на URL Server.
2. Server проверяет метод, общий размер, доступные кредиты и другие правила приёма.
3. Каждый принятый вебхук становится Request в регионе Server и согласно текущей модели оплаты использует один кредит.
4. Adal создаёт независимый Delivery для каждого настроенного Destination.
5. Adal фиксирует каждую попытку и может запланировать автоматический повтор согласно конфигурации Destination.
6. Сохранённые данные Request и история доступны до запланированной даты удаления.

```text
Server
└── Request #1
    ├── Delivery → Destination A → 2xx
    ├── Delivery → Destination B → Waiting for CLI
    └── Delivery → Destination C → Retry scheduled
```

Server без Destinations всё равно может принимать Requests для просмотра, если выбранная конфигурация сохраняет их, но автоматические Deliveries не создаются. Отклонённый запрос не проходит этот цикл: у него нет Deliveries, а Adal сохраняет только минимальные диагностические данные.

## Данные Request {#request-data}

Для принятого Request, сохраняемого выбранной конфигурацией, Adal хранит данные, необходимые для просмотра и Delivery:

- HTTP-метод;
- полный URI, путь и строку запроса;
- заголовки и тело;
- отдельные размеры URI, заголовков и тела, а также общий размер;
- IP-адрес отправителя;
- время получения и запланированную дату удаления;
- Server и регион, принявшие Request;
- статус Request и связанные Deliveries;
- технические идентификаторы, связывающие записи.

Общий размер, сравниваемый с применимым ограничением, рассчитывается так:

```text
размер запроса = размер URI + размер заголовков + размер тела
```

Версия HTTP не хранится как отдельное поле Request. Переданный `User-Agent` остаётся доступен в заголовках. В обзоре также показывается `Content-Type`, но он описывает лишь формат, заявленный отправителем, и не доказывает, что тело является корректным JSON, XML, набором полей формы, текстом или другим заявленным форматом.

Adal не дополняет Request бизнес-данными и не исправляет некорректное содержимое. Проверяйте формат и смысл в приложении Destination.

## Принятые и отклонённые Requests {#accepted-and-rejected}

Принятый Request прошёл проверки Server и аккаунта. Adal может сохранить полный Request согласно выбранной конфигурации, использует один кредит и создаёт Deliveries для текущих Destinations Server.

Общий статус Request рассчитывается по всем связанным Deliveries:

| Статус | Значение |
| --- | --- |
| `received` | Request принят Server без Destinations. |
| `delivering` | Хотя бы один Delivery ещё не достиг окончательного результата. |
| `success` | Все Deliveries завершились успешно. |
| `partial` | Часть Deliveries успешна, а другие исчерпали повторы и завершились ошибкой. |
| `failed` | Все Deliveries исчерпали повторы и завершились ошибкой. |
| `rejected` | Входящий запрос не прошёл правила приёма и не был доставлен. |

Запрос может быть отклонён, если его метод отключён, общий размер превышает текущее ограничение, HTTP-сообщение некорректно, достигнуто ограничение аккаунта, недоступны кредиты или принимающая инфраструктура не может обработать запрос.

Для отклонённого Request Adal сохраняет только минимальную диагностическую информацию: метод, время получения, причину отклонения, а также необходимые технические идентификаторы или рассчитанные счётчики. URI, путь, строка запроса, заголовки, тело, заявленный тип содержимого, IP-адрес отправителя и данные Delivery **не сохраняются**.

У отклонённых Requests нет Deliveries, их нельзя отправить через replay, они не используют кредиты, а отброшенное содержимое невозможно восстановить позднее.

## Просмотр Request {#inspect-request}

Откройте [Requests](https://dashboard.adal.cloud/requests) и выберите запись. Страница разделяет полученные HTTP-данные, состояние Request и технические идентификаторы.

| Панель | Содержимое |
| --- | --- |
| Обзор Request | URI, метод, путь, время, Server, адрес отправителя, статус, тип содержимого, размеры и причина отклонения, если доступна. |
| Параметры запроса | Разобранные параметры и их количество либо пустое состояние. |
| Заголовки | Полученные имена и значения заголовков, а также их количество. |
| Тело | Сохранённое тело, заявленный тип содержимого, предварительный просмотр для поддерживаемых форматов и скачивание. |
| Сводка Delivery | Связанные Deliveries и их общий результат либо пустое состояние. |
| Технические данные | Идентификаторы Request и Server, сведения о регионе и время получения. |

**Full URI** содержит путь и строку запроса, а **Path** — только путь. Значения после `?` также разбираются в панели параметров запроса. Размеры URI, заголовков и тела показаны отдельно; **Total size** является их суммой.

Панели заголовков, параметров и тела сохраняют полученные значения. JSON можно отформатировать для просмотра, а большие, бинарные или неподдерживаемые форматы тела — скачать.

> **Чувствительные данные:** Заголовки, пути, параметры запроса и тело могут содержать токены, подписи, персональные данные и другие секреты. Не копируйте полный Request в обычные логи, аналитику, отчёты об ошибках, публичные задачи или обращения в поддержку.

## Deliveries и история попыток {#delivery-details}

Сводка Delivery перечисляет все Deliveries, связанные с Request. Если Delivery не был создан, страница показывает пустое состояние; это ожидаемо, когда у Server нет Destinations или запрос был отклонён.

Каждый Delivery отслеживается независимо. Request остаётся в статусе `delivering`, пока хотя бы один маршрут активен. Когда все маршруты получают окончательный результат, общий статус становится `success`, `partial` или `failed`.

Любой ответ `2xx` означает успешный Delivery. Ответы `4xx` и `5xx`, тайм-ауты и сетевые ошибки считаются неудачными и могут вызвать автоматический повтор согласно конфигурации Destination.

Подробности Delivery могут содержать:

- текущий статус и время создания;
- номер текущей или последней попытки;
- статус ответа или зафиксированную ошибку;
- продолжительность и время с момента получения Request;
- исходный Request и Destination;
- URL и метод Delivery;
- время и результат каждой попытки.

Adal не хранит заголовки или тело ответа Destination. Используйте результат, время и диагностические сведения вместе с собственными логами приложения Destination.

Ручной повтор снова отправляет существующий Request в один выбранный Destination. Он не создаёт новый Request и не влияет на другие маршруты. Согласно текущей модели оплаты ручной повтор использует один дополнительный кредит, автоматические повторы — нет.

## Replay Request {#replay}

Replay создаёт новый Request из сохранённого и снова отправляет его через текущий процесс Server.

```text
Исходный Request → Replay → Новый Request → Новые Deliveries → Текущие Destinations
```

- исходный Request не изменяется;
- новый Request хранится отдельно и ссылается на исходный;
- Adal использует Destinations, настроенные для Server в момент replay;
- новый Request получает собственные Deliveries и историю попыток;
- согласно текущей модели оплаты replay использует один кредит;
- replay доступен только пока необходимые исходные данные хранятся в Adal.

| Действие | Что создаётся | Область действия |
| --- | --- | --- |
| Автоматический повтор | Ещё одна попытка существующего Delivery. | Один Destination. |
| Ручной повтор | Ещё одно действие Delivery для существующего Request. | Один выбранный Destination. |
| Replay | Новый Request и новые Deliveries. | Текущие Destinations Server. |

Replay может повторить необратимый побочный эффект. До запуска оцените последствия и убедитесь, что все затронутые обработчики безопасно выполнять повторно.

## Дубликаты и идемпотентность {#duplicates-and-idempotency}

Автоматические и ручные повторы могут доставить один Request несколько раз. Replay создаёт новый Request в Adal, но он может представлять то же событие провайдера. Adal не предоставляет exactly-once delivery.

Destination можно настроить на получение заголовка идемпотентности Adal:

```http
X-Adal-Idempotency: <request-key>
```

Deliveries и повторы одного Request используют одинаковый ключ Adal. Replay создаёт новый Request с новым ключом, поэтому один этот заголовок не позволяет обнаружить то же событие провайдера после replay.

Обработчики Destination должны:

- проверять подпись отправителя и валидировать все входные данные;
- быть идемпотентными;
- использовать стабильный идентификатор события провайдера для устранения дублей, если он доступен;
- сохранять идентификатор события атомарно с бизнес-операцией;
- возвращать `2xx` только после принятия ответственности за обработку.

## Retention и удаление {#retention}

Принятые Requests хранятся ограниченное время, определяемое планом и конфигурацией Server. Retention начинается при приёме Request, а в его подробностях указывается запланированная дата удаления, если это применимо.

После окончания retention Adal безвозвратно удаляет сохранённое содержимое Request и связанные данные Delivery. Request больше нельзя просмотреть, восстановить, отправить вручную или через replay.

Удаление Server останавливает приём новых запросов и удаляет его Destinations. Ранее принятые Requests могут оставаться до индивидуальных запланированных дат удаления; удаление Server не превращает Adal в постоянное хранилище этих записей.

> **Важно:** Используйте собственные базы данных, журналы приложения, резервные копии и механизмы восстановления для долгосрочного хранения бизнес-данных. Retention Requests в Adal является временным и зависит от плана.

## Безопасность Requests {#security}

Любой, кто знает публичный URL Server, может отправить на него запрос. Наличие Request и успешный Delivery не доказывают подлинность отправителя или безопасность содержимого.

- проверяйте подписи вебхуков согласно актуальной документации провайдера;
- разрешайте на Server только ожидаемые HTTP-методы;
- валидируйте структуру, типы, размеры, тип содержимого и допустимые значения;
- не считайте одни лишь заголовки или IP-адрес отправителя доказательством подлинности;
- обеспечивайте идемпотентность и учитывайте дубли событий;
- защищайте URL Server, доступ к панели управления, токены и учётные данные Destination;
- выбирайте подходящие регион и срок retention;
- не помещайте полные данные Request в обычные логи, аналитику, уведомления и отчёты об ошибках.

Некоторые схемы подписи требуют точного исходного тела. Если провайдер требует этого, проверяйте подпись по исходным байтам до разбора или повторной сериализации payload.

Adal шифрует чувствительные данные Requests при хранении и использует защищённые соединения при передаче, но не заменяет аутентификацию, авторизацию, валидацию и контроль доступа в вашем приложении.

## Устранение неполадок {#troubleshooting}

**Request не появился в панели управления**

Проверьте полный URL Server, журнал отправителя, существование Server, разрешённый метод, общий размер, кредиты и доступность региона. Также найдите отклонённую запись.

**Request отклонён**

Откройте запись и изучите причину. Сравните метод с конфигурацией Server и помните, что общий размер включает URI и заголовки вместе с телом. Исправьте причину и попросите провайдера повторить событие: отброшенное содержимое недоступно.

**Request принят, но Delivery отсутствует**

Убедитесь, что у Server есть Destination. Проверяйте каждый маршрут независимо: прямой HTTP-сервис может быть недоступен, а маршрут Adal CLI — ожидать подключения.

**Тело отличается от ожидаемого**

Сравните `Content-Type`, сохранённое тело, кодировку и документацию провайдера. Adal сохраняет полученные данные, но не гарантирует, что отправитель сформировал корректное содержимое заявленного формата.

**Adal показывает успех, но операция не выполнена**

Результат `2xx` означает, что Adal получил ожидаемый HTTP-ответ. Проверьте состояние и логи приложения Destination: его внутренняя транзакция, очередь или последующая обработка всё ещё могут завершиться ошибкой.

**Событие обработано дважды**

Проверьте автоматические и ручные повторы, а также replay. Устраняйте дубли по стабильному идентификатору события провайдера. Ключ идемпотентности Adal позволяет распознать повторный Delivery одного Request, но меняется при создании нового Request через replay.

## Связанные страницы {#related-pages}

- [Servers](/docs/servers)
- [Основные понятия](/docs/concepts)
- [Destinations](/docs/destinations)
- [Повторные попытки Delivery](/docs/retries)
- [Хранение данных и retention](/docs/storage)
- [Adal CLI](/docs/adal-cli)
