Skip to main content

API Version

Manage the life cycle of the API, handling multiple versions.


Introduction

API versioning is crucial for managing changes, updates, and improvements to APIs over time. Traefik Hub provides robust support for effectively managing multiple API versions while maintaining backward compatibility and supporting existing clients.

The APIVersion Object

The APIVersion object represents a specific version of an API within Traefik Hub. It allows API owners to effectively manage the lifecycle of their APIs.

When creating a new APIVersion object, you must reference it in its parent API's versions field.

You can expose an APIVersion using the same mechanism as exposing an API, either through an Ingress or IngressRoute annotation: hub.traefik.io/api-version.

warning

An API and its APIVersions must be part of the same namespace.

Example

Let's start with an existing API exposed through an Ingress.

apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: flight-api
namespace: apps
spec:
openApiSpec:
path: /openapi.json

Now, see an example of how you can add two versions to this API, each attached to different Ingresses with the routing mechanism of your choice. Then, the API object only needs to reference its supported versions. Note that the previous API object now references its versions.

Remove the openApiSpec section and reference API Versions
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: flight-api
namespace: apps
spec:
# Remove the openApiSpec section
versions: # Reference the versions (assumed to be in the same namespace)
- name: flight-api-v1
- name: flight-api-v2

Operation Filtering

Operation filtering allows you to restrict user groups to specific OpenAPI operations.

Here's how it works:

  1. Define OperationSets: OperationSets are named collections of OpenAPI operations. For example, you might create an operationSet called "admin" that includes operations to delete customers and retrieve customer statistics, and another called "support" that includes operations to retrieve a list of all customers.
  2. Configure APIAccess: Once you've defined your operationSets, you can reference them in your APIAccess configurations. For instance, you might grant access to the "admin" operationSet to members of the "admin" group and access to the "support" operationSet to members of the "support" group.

OperationSets

An operationSet is composed of:

  • A name, which will be referenced in the APIAccess.
  • A matcher to select the API operation(s) to be included in the operationSet.

Here are examples of how to define operationSets using different matchers:

Path
# Example of versioning an API using `path` for URI path.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
openApiSpec:
path: /api/v2/openapi.json
operationSets:
- name: flight-operations
matchers:
- path: /flights
note
  • Only one of the following path settings is allowed: path, pathPrefix, or pathRegex.
  • You can use the methods option without specifying a path setting (path, pathPrefix, or pathRegex).
  • You can combine a path setting with the methods option.
  • The pathRegex must match both the OpenAPI specification and the request. For example, the request to /flights/:id shouldn't be expressed by /flights/[0-9]+ but by /flights/.+ to satisfy both /flights/{flightID} in the OAS specification and /flights/2 in the actual user request.
Be aware of the subtle configuration difference

Please note the subtle difference between configuring one matcher with multiple options and configuring multiple matchers. The examples below illustrate the difference in the syntax.

One matcher with two options, both of the options must be aligned
operationSets:
- name: read-pets
matchers:
- pathPrefix: /pets
methods:
- GET

Without a Defined HTTP Method

The following example shows an API CRD using an operation matcher with pathPrefix, without any HTTP method defined. This would allow all HTTP methods matching the /flights path prefix. For example, GET /flights, GET /flights/{id}, POST /flights, PUT /flights/{id}.

Without a Defined HTTP Method
# Example of versioning an API using `pathPrefix` for URI path.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
openApiSpec:
path: /api/v2/openapi.json
operationSets:
- name: flight-operations
matchers:
- pathPrefix: /flights

Every Matcher Option Must Align

The next example shows an API CRD using one matcher with two options. One doing path prefix filtering and one doing method filtering.

Both options must be fulfilled.

Setting two options, one with pathPrefix and the other with methods (act as a logical AND).

This allows GET for all operations matching the /flights path prefix. For example, GET /flights, GET /flights/{id}, GET /flights/findByStatus.

Every Matcher Option Must Align
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
openApiSpec:
path: /api/v2/openapi.json
operationSets:
- name: read-flights
matchers:
- pathPrefix: /flights
methods:
- GET

One of the Two Matchers Must Match

The next example shows an API CRD using a combination of two matchers. One doing path prefix filtering and the other doing method filtering.

One of the matchers must fulfil.

Setting two matchers, one with pathPrefix and the other with methods (act as a logical OR).

This allows all operations matching the /flights path prefix. This allows GET operations on all endpoints of the API For example, POST /flights, GET /airports/{id}.

One of the Two Matchers Must Match
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
openApiSpec:
path: /api/v2/openapi.json
operationSets:
- name: read-flights
matchers:
- pathPrefix: /flights
- methods:
- GET