Модуль 11 · Урок 43 із 58

REST API contract: resources, pagination і Problem Details

REST API стає передбачуваним, коли URL називає resource, HTTP semantics лишаються стандартними, collection має стабільну pagination, а errors і compatibility описані як перевірний контракт, а не набір випадкових JSON-відповідей.

RESTPaginationProblem DetailsContracts

Безпечна HTTP-практика модуля 11

Пакет містить synthetic fixtures, loopback-only HTTP server, bounded urllib client, Problem Details і contract tests. Тести виконують реальні request/response лише на 127.0.0.1 без Internet, персональних чи production-даних, credentials і production endpoints.

Завантажити практичний пакет →

Resource — не назва функції

Замість /createTask, /getTasks і /deleteTask resource-oriented API використовує collection /tasks та member /tasks/{task_id}, а intent передає method. Це не косметика: generic tooling, caching, observability і authorization отримують стабільну модель.

IntentRequestТиповий result
ListGET /tasks200 + collection representation
CreatePOST /tasks201 + Location
ReadGET /tasks/{id}200 або 404
ReplacePUT /tasks/{id}200/204 за contract
DeleteDELETE /tasks/{id}204 за contract

Collection потребує deterministic pagination

API фіксує sort order і tie-breaker. Offset pagination проста, але concurrent inserts можуть зрушувати rows. Cursor/keyset pagination кодує позицію після стабільної пари, наприклад (created_at, id). Cursor є opaque для клієнта, але server має валідувати його version, signature/shape і filter compatibility.

{
  "items": [{"id": 41, "title": "Synthetic task"}],
  "next_cursor": "opaque-training-cursor",
  "has_more": true
}

Response contract визначає maximum limit, default limit, empty collection, filter syntax і поведінку invalid cursor.

Problem Details уніфікує errors

RFC 9457 визначає application/problem+json і базові members type, status, title, detail, instance. HTTP status лишається authoritative для generic software; detail допомагає людині, але client не повинен парсити його як machine contract. Для machine-readable domain data додають typed extensions.

{
  "type": "https://api.example.test/problems/invalid-cursor",
  "title": "Invalid pagination cursor",
  "status": 400,
  "detail": "Request a fresh collection page.",
  "instance": "/problems/req-7f2a"
}

Не виносьте internals у detail

Stack trace, SQL, filesystem path, secret, account existence або service topology можуть перетворити зручний error на витік. Public detail проходить окрему security review.

Idempotency захищає create workflow

Коли client не знає, чи POST був оброблений до network failure, повтор може створити duplicate. Узгоджений Idempotency-Key дозволяє server зберегти outcome для ключа, звірити request fingerprint і повернути той самий logical result. Scope, TTL, collision behavior і storage atomicity є частиною contract.

Ключ не робить будь-який action безпечним автоматично: email, payment або webhook потребують власної deduplication/outbox boundary.

API еволюціонує additive-first

Новий optional response field зазвичай сумісніший, ніж перейменування або зміна type. Clients мають ігнорувати документовані unknown fields, а server — не змінювати semantics існуючого field потай. Breaking change потребує version/migration policy, telemetry використання й sunset communication.

1Написати request/response examples.
2Зафіксувати statuses, fields і invariants.
3Перевірити negative cases.
4Запустити local contract tests.

Практичний pack запускає loopback HTTP server на випадковому локальному port і доводить реальний request/response без зовнішньої мережі. Він не заявляє production readiness, load capacity або security certification.

Методичні джерела

Урок, сценарії, пояснення й вправи створені SEOWORK. Посилання ведуть на стандарти та авторитетну офіційну документацію.

Практична перевірка · урок 43 з 47

Закріпіть матеріал уроку

Три сценарні питання. Для зарахування уроку потрібно дати щонайменше дві правильні відповіді.

1. API має endpoints /createTask і /deleteTask. Яке resource-oriented перепроєктування найкраще використовує HTTP semantics?
2. Offset pagination показує duplicate/missing items під час concurrent inserts. Який contract зменшує цю нестабільність?
3. Client надіслав malformed pagination cursor. Який response найкраще узгоджується з RFC 9457-style contract?