GH GambleHub

API linting et analyse statique

1) Pourquoi lier l'API

L'API est un contrat entre les équipes et les intégrateurs externes. Linting et analyse statique :
  • prévenir les modifications incompatibles et implicites ;
  • unifier les statuts, les erreurs, la pagination, la sécurité ;
  • rendre les spécifications vérifiables par machine et les versions prévisibles ;
  • réduire le coût de la rhubarbe et le temps d'onbording.

Principe : "les contrats sont vérifiés automatiquement ; Le PR sans lien vert ne va pas s'effondrer".


2) Objets de linting

1. Contrats : OpenAPI/AsyncAPI/GraphQL SDL, Protobuf/Avro/JSON Schema.
2. Implémentation : stylos REST/gRPC, middleware, codes d'état/en-têtes.
3. Infrastructure : titres de sécurité, limites, stratégies de cache.
4. Artefacts connexes : exemples (exemples), collections Postman, schémas d'erreur.


3) Règles de base pour l'API HTTP (profil recommandé)

3. 1 Notation et URL

snake_case dans les corps JSON, kebab-case dans les voies ou kebab-case uniforme/'/v1/... ".
Les ressources sont au pluriel : '/v1/payments ', imbriquées par '/v1/wallets/{ id }/transactions'.
Identifiants comme path-params : '/v1/payments/{ payment _ id} '(type : string, format : uuid).

3. 2 Méthodes et statuts

« GET » - 200/206 ; « POST » - 201 (+ « Location »), conflits - 409 ; validation - 422 ; les limites sont de 429 (+ « Retry-After »).
Ne pas renvoyer 200 pour les erreurs. Demandes conditionnelles - 304 par « If-None-Match ».

3. 3 Erreurs (format unique)

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

Sont obligatoires : 'code', 'message', 'trace _ id' ; local - via 'Content-Language'.

3. 4 Pagination/filtres

Cursor-based: `page_size`, `page_token`, ответ: `next_page_token`.
Les filtres et le tri sont des whitelists documentés dans 'parameters'.

3. 5 Sécurité

Schéma de sécurité unique : OAuth2/OIDC scopes ou mTLS ; interdire 'http' (seulement 'https').
Ne pas retourner les en-têtes sensibles, masquer les jetons dans les exemples.

3. 6 Limites et dimensions

Limites des titres/corps : 413/414/431 ; documenter les valeurs maximales admissibles.


4) Outils et écosystème

4. 1 OpenAPI

Spectral (JSON/YAML lint), Redocly linter, oas-diff/openapi-diff, schemathesis/dredd (vérifications en cours).

4. 2 Protobuf/gRPC

buf (lint + breaking check), protolint, générateurs SDK ; gnostic pour l'analyse.

4. 3 GraphQL

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

4. 4 Linters de code et SAST

ESLint, golangci-lint, Detekt/Ktlint, Pylint/Flake8, Semgrep (modèles d'odeurs API et sécurité).


5) Exemples de règles : Spectral/Redocly

5. 1 Spectral (exemple '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 : profil 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: []
Recommandations :
  • Ne pas utiliser les numéros de champ ; à supprimer dans 'reserved'.
  • Les nouveaux champs sont « optional » ou en défaut ; ne pas changer les types/sémantiques.

7) Des changements sémantiques et « cassants »

7. 1 HTTP

Exemples de breaking :
  • modifier le type/l'obligation du champ ;
  • supprimer le statut/itinéraire/paramètre ;
  • rétrécissement de l'enum/de l'aire de répartition ;
  • changement de format id (uuid → string).
Nebraiking :
  • l'ajout de champs facultatifs ;
  • les nouveaux statuts qui n'affectent pas le happy-path (par exemple, le « 422 » documenté) ;
  • extension de l'enum.

7. 2 gRPC/Protobuf

Supprime le champ sans 'reserved '/change de numéro - breaking.
Changement de type (int32 → string) - breaking.
Ajouter une nouvelle balise en tant qu'option - généralement safe.


8) Relier les contrats de liaison et le code

La cohérence est assurée par deux flux :

1. Le contrat → le code : génération de stores SDK/serveur, exemples négatifs dans les tests.

2. Code → contrat : tests de spécification, vérification automatique des statuts/titres.

Idées semgrep :
  • interdiction de 'return 200' dans 'error ! = nil' ;
  • « Idempotency-Key » obligatoire sur les itinéraires de paiement par écrit ;
  • masquage des tokens dans les logs.

9) Pipline CI/CD (référence)


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
Le PR doit tomber si :
  • il y a le breaking-diff ;
  • les règles de base (statuts/sécurité/erreurs) ont été enfreintes ;
  • il n'y a pas d'exemples/descriptions de paramètres.

10) Catalogue de règles (modèle pour votre organisation)

Identifiants et types

`_id` — `string`, `format: uuid`.
Les champs monétaires sont 'string '/' decimal' avec scale ; la monnaie est le ISO-4217.

Erreurs

Régime unique (voir § 3. 3), codes : « 400/401/403/404/409/422/429/5xx ».
Toujours "trace _ id' ;" Retry-After "pour 429/503.

Pagination

Seulement cursor ; max 'page _ size' est documenté.

Sécurité

Toutes les opérations sont un bloc 'security' ; les « scopes » sont décrits.
Aucun 'http :' de liens ; TLS 1. 2+.

Cache/idempotence

Для GET — `ETag/Last-Modified`; pour write - 'Idempotency-Key' (le cas échéant).

Documentation

« résumé », « description », exemples de demandes/réponses (valides).


11) Exemples de contrôles automatisés

11. 1 Vérification des titres de sécurité obligatoires (Spectral)

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

11. 2 openapi-diff (pseudo étape CI)


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

11. 3 buf breaking-check


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

12) Observation de la qualité des contrats

Métriques : proportion de PR avec erreurs de linting, temps de fixation, nombre de tentatives de breaking, « dettes » selon les règles.
Dashboards : progrès de la migration vers un schéma d'erreur unifié, couverture par des exemples, stabilité des versions.


13) Anti-modèles

Doc vit séparément du code → dissynchronisation. Gardez le contrat à proximité du service et produisez un artefact versionné.
Linter seulement à la main. J'ai besoin d'un gate PR dur.
Exemples aléatoires (non-deterministic) - flocons dans les vérifications.
Absence d'exemples négatifs et de codes d'erreur.
Rééchantillonnage du schéma d'erreur pour chaque service.
Ignorer Protobuf breaking-checks (changer les balises en un oeil).


14) Spécificité de l'iGaming/finance

Champs monétaires - échelle/arrondi fixe ; interdiction du float.
Les titres obligatoires sont « X-Tenant », « X-Region » et la trace « traceparent ».
Stylos d'écriture de paiement : vérification de la présence de 'Idempotency-Key', 'Retry-After' et sémantique 409/201 correct.
Les webhooks PSP/KYC : HMAC/mTLS sont décrits dans « securitySchemes » ; anti-replay (« X-Timestamp », fenêtre).
Restrictions régionales et localisation des erreurs ('Content-Language').


15) Chèque-liste prod-prêt

  • Spectral/Redocly profils sont formatés et connectés dans pré-commit et PR-gate.
  • Schéma d'erreur et statuts uniques - fixés et vérifiés.
  • openapi-diff/GraphQL Inspector/buf - bloque les modifications de breaking.
  • Les exemples de demandes/réponses sont valides ; pagination/filtres documentés.
  • SecuritySchemes et scopes sont remplis ; Il n'y a pas de liens http.
  • Pour Protobuf : 'reserved'sur les étiquettes distantes ; les nouveaux champs sont optionnels.
  • Semgrep/linters de code inclus ; masquer les secrets dans les loges.
  • CI publie des artefacts contractuels et des rapports de liaison.
  • Pleybuk : comment agir avec le breaking-diffa (rollback, hotfix, notifications aux intégrateurs).

16) TL; DR

Mettez en œuvre le lingage automatique des contrats (Spectral/Redocly, buf/GraphQL Inspector) et sémantique, fixez un schéma d'erreur/statut/pagination/sécurité unique, connectez PR-gate et publiez les contrats en tant qu'artefacts. Tout breaking-diff est un feu stop. Pour l'argent/les paiements - règles spéciales (idempotence, 'Retry-After', HMAC/mTLS).

Contact

Prendre contact

Contactez-nous pour toute question ou demande d’assistance.Nous sommes toujours prêts à vous aider !

Commencer l’intégration

L’Email est obligatoire. Telegram ou WhatsApp — optionnels.

Votre nom optionnel
Email optionnel
Objet optionnel
Message optionnel
Telegram optionnel
@
Si vous indiquez Telegram — nous vous répondrons aussi là-bas.
WhatsApp optionnel
Format : +code pays et numéro (ex. +33XXXXXXXXX).

En cliquant sur ce bouton, vous acceptez le traitement de vos données.