GH GambleHub

API linting і статичний аналіз

1) Навіщо лінтити API

API - контракт між командами і зовнішніми інтеграторами. Лінтинг і статичний аналіз:
  • запобігають несумісним і неявним змінам;
  • уніфікують статуси, помилки, пагінацію, безпеку;
  • роблять специфікації машино-перевіряються і релізи передбачуваними;
  • скорочують вартість рев'ю і час онбордингу.

Принцип: "контракти перевіряються автоматично; PR без зеленого лінтингу не мержиться".


2) Об'єкти лінтингу

1. Контракти: OpenAPI/AsyncAPI/GraphQL SDL, Protobuf/Avro/JSON Schema.
2. Реалізація: REST/gRPC-ручки, middleware, коди статусів/заголовки.
3. Інфраструктура: заголовки безпеки, ліміти, політики кешу.
4. Супутні артефакти: приклади (examples), Postman-колекції, схеми помилок.


3) Базові правила для HTTP API (рекомендований профіль)

3. 1 Нотація та URL

snake_case в тілах JSON, kebab-case в шляхах або однаковий kebab-case/'/v1/...'.
Ресурси - множина: '/v1/payments', вкладені - '/v1/wallets/{ id }/transactions'.
Ідентифікатори як path-params: `/v1/payments/{payment_id}` (тип: string, формат: uuid).

3. 2 Методи і статуси

'GET'- 200/206;'POST'- 201 (+'Location'), конфлікти - 409; валідація - 422; ліміти - 429 (+'Retry-After').
Не повертати 200 для помилок. Умовні запити - 304 по'If-None-Match'.

3. 3 Помилки (єдиний формат)

json
{ "code":"validation_error", "message":"amount must be ≥ 1", "trace_id":"...", "details":[{"field":"amount","reason":"min:1"}] }

Обов'язкові: `code`, `message`, `trace_id`; локаль - через'Content-Language'.

3. 4 Пагінація/фільтри

Cursor-based: 'page _ size','page _ token', відповідь: `next_page_token`.
Фільтри та сортування - whitelists, документовані в'parameters'.

3. 5 Безпека

Однобразовий security-схема: OAuth2/OIDC scopes или mTLS; забороняти «http» (лише «https»).
Не повертати чутливі заголовки, маскувати токени в прикладах.

3. 6 Обмеження та розміри

Ліміти заголовків/тіла: 413/414/431; документуйте максимально допустимі значення.


4) Інструменти та екосистема

4. 1 OpenAPI

Spectral (JSON/YAML linт), Redocly linter, oas-diff/openapi-diff (semantic diff), schemathesis/dredd (виконувані перевірки).

4. 2 Protobuf/gRPC

buf (lint + breaking check), protolint, генератори SDK; gnostic для аналізу.

4. 3 GraphQL

graphql-schema-linter, graphql-inspector (breaking).

4. 4 Кодові лінтери і SAST

ESLint, golangci-lint, Detekt/Ktlint, Pylint/Flake8, Semgrep (шаблони API-запахів і security).


5) Приклади правил: Spectral/Redocly

5. 1 Spectral (приклад'spectral. yaml`)

yaml extends: ["spectral:oas", "spectral:asyncapi"]
rules:
openapi-tags: off info-contact: error no-http: error path-kebab-case:
description: "Paths must be kebab-case"
given: "$.paths[]~"
severity: error then:
function: pattern functionOptions: { match: "^/(?:[a-z0-9]+(?--[a-z0-9]+)/?)+$" }
response-error-schema:
description: "Error responses must use standard schema"
given: "$.paths[][].responses[?(@property >= '400')]"
then:
field: "content.application/json.schema.$ref"
function: truthy id-as-uuid:
given: "$..parameters[?(@.name =~ /.id$/i)]"
then:
field: schema.format function: enumeration functionOptions: { values: ["uuid"] }

5. 2 Redocly (фрагмент'.redocly. yaml`)

yaml apis:
main: openapi.yaml lint:
extends:
- recommended rules:
no-ambiguous-paths: error operation-2xx-only: off operation-success-response:
severity: error where:
subject: response filterInParentKeys: ["200","201","204"]
operation-security-defined: error no-plain-http: error

6) Protobuf/gRPC: buf-профіль

6. 1 `buf. yaml`

yaml version: v2 modules:
- path: proto lint:
use:
- DEFAULT except:
- PACKAGE_VERSION_SUFFIX # используем v1 в package breaking:
use:
- WIRE_JSON deps: []
Рекомендації:
  • Не перевикориставати номери полів; видаляються - в «reserved».
  • Нові поля - «optional» або з дефолтами; не змінювати типи/семантику.

7) Семантичний diff і «ламаючі» зміни

7. 1 HTTP

Breaking-приклади:
  • зміна типу/обов'язковості поля;
  • видалення статусу/маршруту/параметра;
  • звуження enum/діапазону;
  • зміна формату id (uuid → string).
Небрейкінг:
  • додавання необов'язкових полів;
  • нові статуси, що не впливають на happy-path (наприклад, документований'422');
  • розширення enum.

7. 2 gRPC/Protobuf

Видалення поля без'reserved '/зміна номера - breaking.
Зміна типу (int32 → string) - breaking.
Додавання нового тегу як optional - зазвичай safe.


8) Зв'язок лінтингу контрактів і коду

Узгодженість забезпечується двома потоками:

1. Контракт → код: генерація SDK/серверних заглушок, негативні приклади в тестах.

2. Код → контракт: специфікаційні тести, автоматична перевірка статусів/заголовків.

Semgrep-ідеї:
  • заборона'return 200'при'error! = nil';
  • обов'язковий'Idempotency-Key'на write-маршрутах платежів;
  • маскування токенів в логах.

9) CI/CD пайплайн (референс)


pre-commit: spectral lint, redocly lint
PR gate:  openapi-diff (base..PR), buf breaking-check, graphql-inspector build:   schemathesis smoke, unit/integration linters (ESLint/golangci-lint)
release:  publish contracts (artifact/broker), sign & tag
PR повинен падати, якщо:
  • є breaking-diff;
  • порушені базові правила (статуси/безпека/помилки);
  • відсутні приклади/описи параметрів.

10) Каталог правил (шаблон для вашої організації)

Ідентифікатори та типи

`_id` — `string`, `format: uuid`.
Грошові поля - «string »/« decimal» з scale; валюта - ISO-4217.

Помилки

Єдина схема (див. § 3. 3), коди: `400/401/403/404/409/422/429/5xx`.
Завжди'trace _ id';'Retry-After'для 429/503.

Пагінація

Тільки cursor; max'page _ size'документований.

Безпека

Всі операції -'security'блок; описані «scopes».
Ні'http:'посилань; TLS 1. 2+.

Кеш/ідемпотентність

Для GET — `ETag/Last-Modified`; для write -'Idempotency-Key'( де застосовується).

Документація

'summary','description', приклади запитів/відповідей (валідні).


11) Приклади автоматизованих перевірок

11. 1 Перевірка обов'язкових заголовків безпеки (Spectral)

yaml security-headers:
given: "$.paths[][].responses['200'].headers"
then:
function: truthy

11. 2 openapi-diff (псевдо CI-крок)


openapi-diff --fail-on-incompatible base.yaml pr.yaml

11. 3 buf breaking-check


buf breaking --against '.git#branch=main'

12) Спостережуваність якості контрактів

Метрики: частка PR з помилками лінтингу, час фіксу, кількість breaking-спроб, «борги» за правилами.
Дашборди: прогрес міграції на уніфіковану схему помилок, покриття прикладами, стабільність версій.


13) Антипатерни

«Док» живе окремо від коду → розсинхронізація. Тримайте контракт поруч з сервісом і випускайте версіонованим артефактом.
Лінтер тільки вручну. Потрібен жорсткий PR-gate.
Випадкові приклади (non-deterministic) - флейки в перевірках.
Відсутність негативних прикладів і кодів помилок.
Перевидобування схеми помилок для кожного сервісу.
Ігнорування Protobuf breaking-перевірок (змінюють теги «на вічко»).


14) Специфіка iGaming/фінансів

Грошові поля - фіксований масштаб/округлення; заборона float.
Обов'язкові заголовки'X-Tenant','X-Region'і трасування'traceparent'.
Платіжні write-ручки: перевірка наявності'Idempotency-Key','Retry-After'і коректних 409/201 семантик.
Вебхуки PSP/KYC: HMAC/mTLS описані в'securitySchemes'; anti-replay («X-Timestamp», вікно).
Регіональні обмеження та локалізація помилок ('Content-Language').


15) Чек-лист prod-готовності

  • Spectral/Redocly профілі оформлені і підключені в pre-commit і PR-gate.
  • Єдина схема помилок і статуси - зафіксовані і перевіряються.
  • openapi-diff/GraphQL Inspector/buf - блокують breaking-зміни.
  • Приклади запитів/відповідей валідні; пагінація/фільтри документовані.
  • SecuritySchemes і scopes заповнені; http-посилань немає.
  • Для Protobuf: 'reserved'на видалених тегах; нові поля - optional.
  • Semgrep/лінтери коду включені; маскування секретів в логах.
  • CI публікує артефакти контрактів і звіти лінтингу.
  • Плейбук: як діяти при breaking-диффі (rollback, hotfix, повідомлення інтеграторам).

16) TL; DR

Впроваджуйте автоматичний лінтинг контрактів (Spectral/Redocly, buf/GraphQL Inspector) і семантичний diff, зафіксуйте єдину схему помилок/статусів/пагінації/безпеки, підключіть PR-gate і публікацію контрактів як Артефакти. Будь-який breaking-дифф - стоп-сигнал. Для грошей/платежів - особливі правила (ідемпотентність,'Retry-After', HMAC/mTLS).

Contact

Зв’яжіться з нами

Звертайтеся з будь-яких питань або за підтримкою.Ми завжди готові допомогти!

Розпочати інтеграцію

Email — обов’язковий. Telegram або WhatsApp — за бажанням.

Ваше ім’я необов’язково
Email необов’язково
Тема необов’язково
Повідомлення необов’язково
Telegram необов’язково
@
Якщо ви вкажете Telegram — ми відповімо й там, додатково до Email.
WhatsApp необов’язково
Формат: +код країни та номер (наприклад, +380XXXXXXXXX).

Натискаючи кнопку, ви погоджуєтесь на обробку даних.