Опирается на правила:
R-HDR-1..4иR-HDR-X1из REST API Style Guide → раздел Заголовки и трассировка.
Важно знать
- Стандартные HTTP-заголовки — по назначению (
Content-Type,Authorization,Location,ETag).- Кастомные заголовки — с доменным префиксом единым для всех сервисов проекта.
Idempotency-Keyдля POST-запросов, безопасных при повторной отправке.traceparent(W3C Trace Context) — для distributed tracing.trace-idизtraceparentиспользуется какtraceIdв теле ошибки RFC 9457.- Префикс
X-в кастомных заголовках — устарел по RFC 6648.
Заголовки несут метаданные о запросе/ответе. Большинство уже стандартизировано HTTP (Content-Type, Accept, Authorization). UCP формулирует две дополнительные конвенции: Idempotency-Key для безопасности retry и traceparent для distributed observability.
Стандартные заголовки
R-HDR-1: используются по назначению.
| Header | Назначение | Пример |
|---|---|---|
Content-Type | тип тела запроса/ответа | application/json |
Accept | ожидаемый тип ответа | application/json |
Authorization | аутентификация | Bearer eyJhbGci... |
Location | URL созданного ресурса при 201 Created | /api/v1/orders/550e... |
ETag | версия ресурса для кеширования | "33a64df5" |
If-None-Match | условный GET | "33a64df5" |
If-Match | optimistic concurrency для PUT/PATCH | "33a64df5" |
Cache-Control | кеширование response | no-cache, max-age=300 |
GET /api/v1/orders/550e8400-...
Accept: application/json
Authorization: Bearer eyJhbGci...
If-None-Match: "33a64df5"
HTTP/1.1 200 OK
Content-Type: application/json
ETag: "33a64df5"
Cache-Control: private, max-age=60
Кастомные заголовки с доменным префиксом
R-HDR-2: единый префикс для всех сервисов компании.
Shop-Request-Id: 550e8400-e29b-41d4-a716-446655440000
Shop-Client-Version: 2.1.0
Shop-Tenant-Id: acme
Shop-— выбранный префикс (пример, в реальном проекте — свой).- Един для всех сервисов — order-service, payment-service, billing-service — все используют
Shop-*. - Фиксируется в стандартах команды один раз, не варьируется.
Shop-Request-Id ≠ traceparent:
Shop-Request-Id— идентификатор конкретного запроса от клиента (для дедупликации, логирования).traceparent— идентификатор всей цепочки вызовов (distributed trace).
Idempotency-Key
R-HDR-3: безопасный retry.
POST /api/v1/orders
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json
{ "items": [...] }
Контракт:
- Клиент один раз генерирует ключ на бизнес-операцию.
- Повторный POST с тем же ключом → backend возвращает первый результат, не создаёт дубль.
- Другой payload с тем же ключом →
409 Conflict.
Для money — обязателен (AUTH-19). См. Auth → idempotency.
@PostMapping("/orders")
public ResponseEntity<OrderResponse> create(
@RequestHeader("Idempotency-Key") String key,
@RequestBody @Valid CreateOrderRequest request
) { ... }
Реализация — Distributed → idempotency (idempotency_record таблица).
traceparent — W3C Trace Context
R-HDR-4: distributed tracing.
Стандарт: W3C Trace Context.
traceparent: {version}-{trace-id}-{parent-id}-{trace-flags}
00-1f2a8b6c7d3e4f5a9b0c1d2e3f4a5b6c-7a8b9c0d1e2f3a4b-01
│ │ │ │
│ trace-id (32 hex) parent-id (16) flags
version
- version — формат, сейчас всегда
00. - trace-id — 32 hex, уникальный ID всей цепочки вызовов.
- parent-id — 16 hex, ID текущего span.
- trace-flags — 2 hex, например
01= sampled.
Правила обработки
Client → Service A → Service B → Service C
↓
Service B продолжает trace
- Клиент прислал
traceparent→ сервис использует егоtrace-id, создаёт новыйparent-idдля своего span. - Клиент не прислал → сервис генерирует
traceparentна входе. - trace-id из
traceparentиспользуется какtraceIdв теле ошибки RFC 9457 (см. Ошибки).
В Spring OpenTelemetry — автоматически:
opentelemetry-spring-boot-starterизвлекаетtraceparent.- Прокидывает в outgoing HTTP / Kafka headers.
traceId/spanIdв MDC для логов.
Подробнее — Observability → tracing.
tracestate
Опциональный, для vendor-специфичных данных:
traceparent: 00-1f2a8b6c...-7a8b9c0d...-01
tracestate: vendor1=value1,vendor2=value2
Большинству приложений не нужен — Spring OpenTelemetry заполняет если используется vendor-specific tracer.
Запреты
X- префикс — устарел
R-HDR-X1: запрещено.
X-Request-Id: ... ✗ — устарело по RFC 6648
Shop-Request-Id: ... ✓ — доменный префикс
RFC 6648 (June 2012) официально deprecated X- префикс для кастомных заголовков. Альтернативы:
- Доменный префикс компании (
Shop-,Bank-). - Стандартизованные headers (если применимо —
Authorization,Content-Type).
Исключения (исторические, всё ещё используются):
X-Forwarded-For— стандарт de facto для proxy chain.X-Request-Id— широко используется, но в новых проектах лучшеShop-Request-Id.
Что запрещено
| Антипаттерн | Правило | Что взамен |
|---|---|---|
X-Custom-Header префикс | R-HDR-X1 | доменный префикс компании |
| Кастомный header без префикса | R-HDR-2 | Shop-* consistent |
Authorization без Bearer для JWT | R-HDR-1 | Bearer eyJhbGci... |
| Idempotency-Key для GET | R-HDR-3 | только POST/PATCH |
Самописный Tracking-Id вместо traceparent | R-HDR-4 | W3C standard |
| trace-id 16 hex (не 32) | R-HDR-4 | 32 hex |
| Header в body вместо HTTP header | R-HDR-1 | в HTTP headers |
X-Forwarded-For для tenant-routing | R-HDR-2 | Shop-Tenant-Id |
Куда дальше
- REST API → Заголовки (нормативно) — формулировки.
- Auth → idempotency —
Idempotency-Keyдля money. - Distributed → idempotency — реализация на backend.
- Observability → tracing — OpenTelemetry,
traceparentpropagation. - Observability → context propagation — MDC
traceId. - Ошибки RFC 9457 —
traceIdв теле ошибки. - JSON и формат ответов —
Locationдля 201.