GH GambleHub

API lining and static analysis

1) Why link API

API - a contract between teams and external integrators. Linting and static analysis:
  • Prevent incompatible and implicit changes
  • unify statuses, errors, pagination, security;
  • make specifications machine-verifiable and releases predictable;
  • reduce the cost of review and onboarding time.

Principle: "contracts are checked automatically; PR without green linting does not hold."


2) Linting facilities

1. Contracts: OpenAPI/AsyncAPI/GraphQL SDL, Protobuf/Avro/JSON Schema.
2. Implementation: REST/gRPC pens, middleware, status codes/headers.
3. Infrastructure: security headers, limits, cache policies.
4. Related artifacts: examples, Postman collections, error schemes.


3) Basic rules for HTTP API (recommended profile)

3. 1 Notation and URL

snake_case in JSON bodies, kebab-case in paths, or uniform kebab-case/'/v1/... '.
Resources - plural: '/v1/payments', nested - '/v1/wallets/{ id }/transactions'.
Identifiers as path-params: '/v1/payments/{ payment _ id} '(type: string, format: uuid).

3. 2 Methods and statuses

'GET '- 200/206;' POST '- 201 (+' Location '), conflicts - 409; validation - 422; limits - 429 (+ 'Retry-After').
Do not return 200 for errors. Conditional Queries - 304 by'If-None-Match '.

3. 3 Errors (single format)

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

Required: 'code', 'message', 'trace _ id'; locale - via 'Content-Language'.

3. 4 Pagination/filters

Cursor-based: `page_size`, `page_token`, ответ: `next_page_token`.
Filters and sorting - whitelists documented in 'parameters'.

3. 5 Safety

Uniform security scheme: OAuth2/OIDC scopes or mTLS; deny 'http' (only 'https').
Do not return sensitive headers, mask tokens in examples.

3. 6 Limitations and dimensions

Title/body limits: 413/414/431; Document the maximum allowed values.


4) Tools and ecosystem

4. 1 OpenAPI

Spectral (JSON/YAML lint), Redocly linter, oas-diff/openapi-diff (semantic diff), schemathesis/dredd (checks in progress).

4. 2 Protobuf/gRPC

buf (lint + breaking check), protolint, SDK generators; gnostic for analysis.

4. 3 GraphQL

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

4. 4 Code Linters and SAST

ESLint, golangci-lint, Detekt/Ktlint, Pylint/Flake8, Semgrep (API odor and security templates).


5) Rule examples: Spectral/Redocly

5. 1 Spectral (example '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 (fragment '.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 profile

6. 1 `buf. yaml`

yaml version: v2 modules:
- path: proto lint:
use:
- DEFAULT except:
- PACKAGE_VERSION_SUFFIX # используем v1 в package breaking:
use:
- WIRE_JSON deps: []
Recommendations:
  • Do not reuse field numbers; deleted - in'reserved '.
  • New fields - 'optional' or with defaults; do not change types/semantics.

7) Semantic diff and "breaking" changes

7. 1 HTTP

Breaking examples:
  • Change field type/mandatory
  • Delete status/route/parameter
  • enum/range narrowing;
  • change of id (uuid → string) format.
Non-breaking:
  • Add optional fields
  • New statuses that do not affect the happy path (for example, documented '422')
  • enum extension.

7. 2 gRPC/Protobuf

Deleting a field without'reserved '/renumbering - breaking.
Type change (int32 → string) - breaking.
Adding a new tag as optional is usually safe.


8) Contract and Code Linking

Consistency is provided by two threads:

1. Contract → code: generation of SDK/server stubs, negative examples in tests.

2. Contract → code: specification tests, automatic check of statuses/headers.

Semgrep ideas:
  • disallowing'return 200'when'error! = nil';
  • mandatory'Idempotency-Key 'on write payment routes;
  • masking tokens in logs.

9) CI/CD pipeline (reference)


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 shall fall if:
  • there is breaking-diff;
  • Basic rules have been violated (statuses/security/errors)
  • there are no examples/descriptions of parameters.

10) Rules catalog (template for your organization)

Identifiers and types

`_id` — `string`, `format: uuid`.
Money fields - 'string '/' decimal' with scale; currency - ISO-4217.

Mistakes

Unified scheme (see § 3. 3), codes: '400/401/403/404/409/422/429/5xx'.
Always' trace _ id ';' Retry-After'for 429/503.

Pagination

Cursor only; max'page _ size'is documented.

Safety

All operations - 'security' block; 'scopes' are described.
No 'http:' links; TLS 1. 2+.

Cache/idempotency

Для GET — `ETag/Last-Modified`; for write - 'Idempotency-Key' (where applicable).

Documentation

'summary ',' description ', examples of requests/responses (valid).


11) Examples of automated checks

11. 1 Verification of mandatory security headers (Spectral)

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

11. 2 openapi-diff (pseudo CI step)


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

11. 3 buf breaking-check


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

12) Observability of quality of contracts

Metrics: share of PRs with linking errors, fix time, number of breaking attempts, "debts" according to the rules.
Dashboards: migration progress to the unified error scheme, coverage with examples, version stability.


13) Antipatterns

"Doc" lives separately from the code → desynchronization. Keep the contract close to the service and release a versioned artifact.
Linter only by hand. Need a hard PR-gate.
Random examples (non-deterministic) - flakes in checks.
No negative examples and error codes.
Reinvention of the error scheme for each service.
Ignoring Protobuf breaking checks (changing tags "by eye").


14) Specifics of iGaming/Finance

Currency fields - fixed scale/rounding; float prohibition.
Mandatory headers' X-Tenant ',' X-Region'and trace' traceparent '.
Payment write-handles: checking for 'Idempotency-Key', 'Retry-After' and correct 409/201 semantics.
Webhooks PSP/KYC: HMAC/mTLS are described in 'securitySchemes'; anti-replay ('X-Timestamp', window).
Regional restrictions and error localization ('Content-Language').


15) Prod Readiness Checklist

  • Spectral/Redocly profiles are designed and connected in pre-commit and PR-gate.
  • Single error pattern and statuses - committed and checked.
  • openapi-diff/GraphQL Inspector/buf - block breaking changes.
  • Examples of requests/responses are valid; pagination/filters documented.
  • SecuritySchemes and scopes are filled; There are no http links.
  • For Protobuf: 'reserved' on deleted tags; new fields - optional.
  • Semgrep/code linters enabled; masking secrets in logs.
  • CI publishes contract artifacts and linting reports.
  • Playbook: how to act when breaking-diffa (rollback, hotfix, notifications to integrators).

16) TL; DR

Implement automatic contract linting (Spectral/Redocly, buf/GraphQL Inspector) and semantic diff, fix a single error/status/pagination/security scheme, connect PR-gate and publish contracts as artifacts. Any breaking diff is a brake light. For money/payments - special rules (idempotency, 'Retry-After', HMAC/mTLS).

Contact

Get in Touch

Reach out with any questions or support needs.We are always ready to help!

Start Integration

Email is required. Telegram or WhatsApp — optional.

Your Name optional
Email optional
Subject optional
Message optional
Telegram optional
@
If you include Telegram — we will reply there as well, in addition to Email.
WhatsApp optional
Format: +country code and number (e.g., +380XXXXXXXXX).

By clicking this button, you agree to data processing.