Docs API Versioning

API Versioning

APIs do not fail when they are wrong.

They fail when they change unexpectedly.

Once an API is consumed by:

  • Frontends
  • Mobile apps
  • Third-party services
  • Partners
  • Automation scripts

It becomes a contract.

Plumego does not impose an API versioning strategy — deliberately.
But it enforces constraints that make good versioning strategies possible.

This document explains how to evolve APIs explicitly, safely, and predictably.


First Principle: Versioning Is a Contract Decision

API versioning is not a routing trick.

It is a contract and communication decision.

If you treat versioning as:

  • A convenience
  • A refactor aid
  • A framework feature

You will break clients.

In Plumego’s worldview:

Versioning decisions live at the boundary — where contracts are defined.


When You Actually Need a New Version

You need a new API version when you introduce:

  • Breaking request/response shape changes
  • Semantic changes to behavior
  • Different authorization rules
  • Different validation rules
  • Different error semantics

You do not need a new version for:

  • Adding optional fields
  • Adding new endpoints
  • Improving internal performance
  • Refactoring internal code

Backward compatibility is a discipline, not an accident.


Supported Versioning Strategies

Plumego supports all common strategies — explicitly.

1. Path-Based Versioning

Example:

/api/v1/orders
/api/v2/orders

Implementation:

  • Separate route groups
  • Separate handlers
  • Possibly separate usecases

This is the most explicit and debuggable strategy.

Recommended for public APIs.


2. Header-Based Versioning

Example:

X-API-Version: 2
Accept: application/vnd.example.v2+json

Implementation:

  • Pre-dispatch routing
  • Explicit handler selection
  • No hidden fallbacks

This strategy keeps URLs clean but increases routing complexity.


3. Host-Based Versioning

Example:

v1.api.example.com
v2.api.example.com

Implementation:

  • External routing (gateway or server mux)
  • Separate Plumego apps per version

This is operationally clean but infrastructure-heavy.


What Plumego Does Not Do

Plumego does not:

  • Auto-negotiate versions
  • Guess client intent
  • Provide implicit fallbacks
  • Inject versioning logic into handlers
  • Rewrite responses silently

If a request hits a versioned handler,
it is because you routed it there explicitly.


Versioning and Routing Structure

A recommended structure for path-based versioning:

internal/
api/
v1/
orders/
handler.go
v2/
orders/
handler.go

Each version:

  • Has its own handlers
  • Owns its own contracts
  • Can evolve independently

Shared logic should live below the API layer.


Versioning and Usecases

Important rule:

Do not version usecases unless behavior truly diverges.

Common pattern:

  • One usecase
  • Multiple handlers (v1, v2)
  • Different request/response mapping

Only introduce versioned usecases when:

  • Business semantics differ
  • Authorization rules change
  • Side effects change

Avoid duplicating business logic just to version APIs.


Deprecation Before Removal

Removing APIs without warning is hostile.

A responsible lifecycle:

  1. Introduce new version
  2. Mark old version as deprecated
  3. Communicate timelines clearly
  4. Monitor usage
  5. Remove only when safe

Deprecation is a process, not a flag.


Versioning and Error Semantics

Error responses are part of the contract.

Changing:

  • Status codes
  • Error formats
  • Error meanings

Is a breaking change.

If error semantics change,
they must be versioned like any other behavior.


Documentation and Versioning

Every API version must have:

  • Its own documentation
  • Clear changelogs
  • Explicit status (active / deprecated)

Plumego Docs should reflect versions explicitly.

Undocumented versions are operational debt.


Testing Versioned APIs

Testing must respect version boundaries:

  • Separate handler tests per version
  • Shared usecase tests where behavior is shared
  • Regression tests for deprecated versions
  • Contract tests for external consumers

Never assume “it still works” without tests.


Avoiding Version Explosion

Versioning has a cost.

Avoid creating new versions for:

  • Minor field additions
  • Internal refactors
  • Performance improvements

Prefer additive changes whenever possible.

A small number of long-lived versions
is far healthier than many short-lived ones.


Anti-Patterns to Avoid

Silent Behavior Changes

Same endpoint, different behavior — without a version bump.

This is the fastest way to lose trust.


Version Logic Inside Handlers

if version == "v2" { ... }

This mixes contracts and logic and becomes unmaintainable.


“Latest” as a Version

“Latest” is not a contract.
It is a moving target.


Versioning and Multi-Service Systems

In multi-service setups:

  • Each service versions independently
  • Internal APIs still need contracts
  • Version skew must be expected

Do not rely on synchronized upgrades.

Explicit versioning reduces coordination cost.


Summary

In Plumego:

  • API versions are explicit contracts
  • Routing makes version choice visible
  • Handlers define version boundaries
  • Usecases remain stable when possible
  • Breaking changes are deliberate
  • Clients are respected

API versioning is not about change —
it is about changing without betrayal.


Advanced Section: Complete

With API versioning covered, the Advanced section now forms a complete arc:

  • Custom routing
  • Embedding
  • Multi-service setups
  • Performance
  • Component replacement
  • Background processing
  • API evolution

All without breaking Plumego’s core guarantees.

From here, the system is ready to live for years.