This document describes the API versioning architecture in Flight Control.
Flight Control uses HTTP header-based versioning rather than URL-based versioning. Clients specify their desired API version using the Flightctl-API-Version header, and the server negotiates the appropriate version based on endpoint support.
API versions are per-resource (e.g., Device, Fleet, Repository). Each resource can have different supported versions, allowing resources to evolve independently.
| Header | Direction | Purpose |
|---|---|---|
Flightctl-API-Version |
Request | Client specifies desired version |
Flightctl-API-Version |
Response | Server returns negotiated version |
Flightctl-API-Versions-Supported |
Response (406 only) | Lists supported versions on error |
Deprecation |
Response | RFC 9745 header with RFC 9651 date format @<epoch-seconds> indicating when the version was or will be deprecated |
Vary |
Response | Set to Flightctl-API-Version for cache differentiation |
- Client sends request with optional
Flightctl-API-Versionheader - Server determines negotiated version based on endpoint metadata derived from OpenAPI specs (
api/{group}/{version}/openapi.yaml):- If version requested and supported: use requested version
- If version requested but not supported: return HTTP 406 Not Acceptable
- If no version requested: use first (most preferred) version from metadata
- For versioned resources, server responds with
Flightctl-API-Versionheader indicating negotiated version
# Request specific version
curl -H "Flightctl-API-Version: v1beta1" \
https://api.flightctl.example.com/api/v1/devices
# Response headers include:
# Flightctl-API-Version: v1beta1
# Vary: Flightctl-API-Version# Request unsupported version
curl -H "Flightctl-API-Version: v2" \
https://api.flightctl.example.com/api/v1/devices
# Response headers include:
# Flightctl-API-Versions-Supported: v1beta1
# HTTP/1.1 406 Not Acceptable| Level | Description | Support Guarantee |
|---|---|---|
v1alphaX |
Alpha versions | TBD |
v1betaX |
Beta versions | Supported throughout the 1.x.x major version |
v1 |
Stable version | TBD |
Request with Flightctl-API-Version header
|
v
+------------------------+
| Negotiator |
+------------------------+
|
v
+------------------------+
| Dispatcher |
+------------------------+
/ \
v v
+-----------+ +-----------+
| v1beta1 | | v1 |
| Router | | (future) |
+-----------+ +-----------+
| |
v v
+-----------+ +-----------+
| v1beta1 | | v1 |
| Transport | | Transport |
+-----------+ +-----------+
| |
v v
+-----------+ +-----------+
| v1beta1 | | v1 |
| Converter | | Converter |
+-----------+ +-----------+
\ /
v v
+------------------+
| Domain Types |
+------------------+
- Negotiator - Middleware that handles version negotiation and sets response headers
- Dispatcher - Routes requests to the appropriate version-specific router
- Transport Handlers - Implement the API endpoints for each version, located in
internal/transport/{version}/ - Converters - Translate between versioned API types and internal domain types, located in
internal/api/convert/{version}/ - Domain Types - Internal representation of resources in
internal/domain/, currently type aliases to API types
- Create OpenAPI spec - Add a new version directory under
api/{group}/{version}/with the OpenAPI specification - Add version constant - Register the new version in
internal/api_server/versioning/version.go - Generate types - Run
make generateto create API types and endpoint metadata - Create transport handlers - Implement API endpoint handlers in
internal/transport/{version}/ - Create converters - Add converters in
internal/api/convert/{version}/to translate between API and domain types - Update domain types - If the new version has breaking changes, update domain types to support both versions
- Register the router - Wire up the new version router in
internal/api_server/server.go