GH GambleHub

API versioning and contract compatibility

TL; DR

Compatibility is discipline, not luck. Keep a clear version policy (SemVer), change math (what "breaks," what doesn't), contract tests, schema registers, and Sunset procedures. For money and compliance - strict REST/gRPC with vN, for UI aggregations - evolutionary GraphQL with '@ deprecated'. Always: canary traffic, backward compatibility ≥ one release cycle, migration guides, field telemetry.

1) Basic concepts and goals

Backwards-compatible (BC): old clients are suitable for the new server.
Forwards-compatible (FC): new clients are suitable for the old server (limited).
Wire compatibility: the format on the "wire" does not break (especially important for gRPC/Protobuf).
SemVer: `MAJOR. MINOR. PATCH '- break the contract → raise MAJOR.

The goal is to minimize disruptive changes and provide predictable migration windows.

2) Change Matrix: What you can and can't

Type of changeRESTgRPC (Protobuf)GraphQL
Add a field (response)+ safe+ safe (new field number)+ safe
Add Optional Field (request)️ if the server tolerates the absence of+ safe+ safe
Delete Field- breaking- if you reuse the number️ after '@ deprecated' → delete after window
Rename Field- breaking- (change name, keep number)️ alias/two time fields
Change Type/Format- breaking- at change of wire-type- if breaks the circuit
Change status/error semantics- breaking- codes/parts - contract- breaks customers
Change order in Enum️ by value is safe️ if enum numbers are stable+ by name safe
New endpoint/methods+ safe+ safe+ safe
Changing pagination/filters️ carefully, add options+ via new fields+ through new arguments

3) Policies for different API styles

3. 1 REST

Version in URI ('/v1/... ') or domain (' api-v1. '). Header version - for internal cases only.
Add, do not delete: new fields - ok, old - mark as' deprecated'in the diagram and leave for at least one cycle.
Statuses/errors: do not change the codes and structure'error. code/error. message/error. details`.
Idempotency is unchanged: do not turn a secure 'POST' with 'Idempotency-Key' into a 'behaviorally different' challenge.

3. 2 gRPC / Protobuf

Field numbers are sacred: do not reuse deleted numbers, mark as' reserved '.
Only adding new optional/repit fields; "hard mandatory" - through validation, not'required '.
Version packages: 'payments. v1`, `payments. v2`.
Service compatibility: new RPCs → a new method; we do not change the behavior of the old.

proto message Payout {
reserved 4 ;//field deleted, number reserved string id = 1;
string currency = 2;
int64 amount_minor = 3;
// v2: optional string comment = 5;
}

3. 3 GraphQL

Evolution without v2: add fields/types; deletion - through '@ deprecated (reason)' with the announcement of the window.
Persisted Queries: For public clients, use a whitelist of queries - it's easier to control compatibility.
Field-level authZ and telemetry: know which fields are actually used before deleting.

graphql type Payout {
id: ID!
amountMinor: Long!
currency: String!
comment: String @deprecated(reason: "Use note")
note: String
}

3. 4 Webhooks

Version in path ('/webhooks/v1/payments') and fixed event envelope ('event _ id', 'type', 'ts', 'data').
Keep signatures/NMAS unchanged; new algorithms - as an option with a flag.
Extensions - only through the new fields' data. 'and' headers' - without deleting the old ones.

4) Gateway API and version routing

Rules-based routing: by prefix '/v1 ', by header' X-Api-Version ', by domain.
Shadow/Canary: Reflect some of the production traffic on the new version "into the shadows," compare the answers.
Rate/Quotas per-version: Protects older clients during migration.

Sunset headers for REST:
  • 'Sunset: '- version shutdown date
  • 'Deprecation: true '- version becomes obsolete
  • `Link: ; rel = "deprecation" '- on changelog/migration guide
Example (Nginx-style, simplified):
nginx location ~ ^/v2/ {
proxy_pass http://api_v2;
}
location ~ ^/v1/ {
add_header Deprecation "true";
add_header Sunset "Thu, 01 May 2026 00:00:00 GMT";
proxy_pass http://api_v1;
}

5) Scheme registers and contracts

OpenAPI / JSON Schema для REST; Protobuf descriptors для gRPC; SDL registry для GraphQL.
CI checks: linters + "breaking-changes check" in PR.
Consumer-Driven Contracts (CDC): Consumer tests (Pact/analog) - protection against inconspicuous breaks.
Changelog: machine-readable (for example, 'CHANGELOG. md '+ release notes in the registry).

6) Evolution of fields: rules of thumb

ID/keys: do not change the format (UUID↔int) without a new field '_ v2' and a transition period.
Time/currency: keep UTC ISO-8601/epoch and amount_minor + currency; do not scale (pennies/cents).
Enum: add values - ok; don't change the meaning of old ones. For REST, give string values, not ints.
Pagination: cursor-based more stable; do not change the semantics of the cursor.

7) Depletion and "Sunset" procedure

1. Announcement (T-90/60): changelog, mailing to partners, 'Deprecation/Sunset' headlines.
2. Duplicate period: V1 and V2 operate in parallel; V1 is equipped with warnings in responses/logs.
3. Usage telemetry: Who else calls V1? point contacts.
4. Freezing V1: only bug fixes/no feature.
5. Sunset-410 Gone or migration instruction block page.

8) Pain-free releases: laying strategies

Blue/Green or Weighted routing: 1-5-25-50-100% traffic.
Compatibility window: at least 1-2 minor releases, more often 6-12 months for external APIs.
Feature Flags to include new logic fields/branches without upgrading.
Read/Write-split: first add support for reading a new field, then start writing it.

9) Interoperability testing (practice suite)

Golden tests for responses from older versions.
Diff tests of circuits: no breaking in CI.
Replay production runs on staging for V2 (shadow).
Back/Forward scripts: new client on the old server and vice versa (where FC is valid).
Contract tests of webhooks: verification of signature, format, time.

10) Metrics and SLOs of the versioning process

% of customers on the last MINOR (target ≥ 80% before Sunset).
Compatibility/unavailability errors per release (target 0).
Share of legacy calls (decreasing to Sunset).
Client migration time (median/p95).
Latency/regression delta between versions (not worse than basic).

11) Examples of artifacts

OpenAPI (fragment, field depriction):
yaml components:
schemas:
Payout:
type: object properties:
id: { type: string, format: uuid }
amount_minor: { type: integer }
currency: { type: string }
comment:
type: string deprecated: true description: "Use note"
note: { type: string }
Protobuf (reserved and v2 packet):
proto syntax = "proto3";
package payouts. v1;
message Payout { reserved 5; string id=1; int64 amount_minor=2; string currency=3; }
GraphQL (depletion):
graphql type Query { payout(id: ID!): Payout }

12) Versioning of adjacent channels

SDK/CLI: SemVer + API version dependency, compatibility stipulated in README.
Events/streams (WS/Kafka): version in'envelope. version`; new attributes - optional; dedup and resumes work the same between versions.
Reporting/CSV: version in file name/header; Add columns to the right do not change the order/types.

13) Governance and roles

Contract owner (domain owner), Steward API (rules and linters), Release Manager (Sunset/communications).
RFC process for breaking changes: business justification, migration plan, artifacts, dates.
Unified API directory: where diagrams, versions, Sunset calendar, contact are visible.

14) Anti-patterns

"Quiet" breaks: change the status/error/field type without a version.
Reuse of protobuf numbers - destroys replay and old clients.
GraphQL without field telemetry - touch removal.
Global v2 total - megamigration instead of point evolution.
The version in the query parameter for the public API is a non-obvious and vulnerable scheme.
There are no migration guides and examples - partners stall, deadlines are disrupted.

15) Check-list release of the new version

  • Updated schema (OpenAPI/Protobuf/SDL), linters and breaking-checks passed.
  • Integration and contract tests (CDC) added.
  • SDK/sample code/migration guide and Changelog ready.
  • Deprecation/Sunset enabled (old version) + How to migrate page.
  • Canary/Shadow plan, alerts and dashboards comparing metrics.
  • Backward compatibility is maintained for an agreed period.
  • Rollback plan and risk matrix agreed.

Summary

A stable API is a process, not "once and for all." Live by the rules: SemVer + add-only evolution + circuit register + contract tests + Sunset procedures. Separate styles (REST/gRPC/GraphQL) and their policies, route versions to the Gateway API, roll out canaries, measure the effect. This way you will avoid "breaking surprises," accelerate partner integration and maintain predictability for monetary and compliance-critical domains.

Contact

Get in Touch

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

Telegram
@Gamble_GC
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.