API
Manage APIs with Traefik Hub.
Introduction
An API, or Application Programming Interface, is a set of rules and tools that allows different software applications to communicate with each other.
Traefik Hub helps you publish and secure access to your APIs.
The API Object
In Traefik Hub, you describe your APIs using K8S objects (see API CRD Reference).
Like every Traefik Hub object, you will assign APIs a name and labels / selectors for future reference and management at scale.
An API points to a K8S service (that implements the API itself) and references an Open API Specification file or path that will be used in the Portal.
APIs need to be published through a Gateway to be accessible. Users will then need proper access to consume them, up to their quota.
You must define either a service
(no version) or a currentVersion
, in which case you need to declare a matching API Version.
You cannot use both.
Whenever there are multiple versions of an API, CORS are defined within each version.
Managing APIs using CRDs
Reference
Field | Description | Required |
---|---|---|
metadata.name | Unique name of an API. We recommend using kebab-case, for example, my-api. | Yes |
metadata.labels | See Labels and Selectors. | No |
spec.pathPrefix | The path prefix of the API, for example /customers. The path prefix will append the URL of the API Gateway. | Yes |
spec.currentVersion | Marks an API as "versioned" and specifies the default version of the API that will appear in the API Portal. If spec.currentVersion is used, the Service must be defined in the APIVersion. | No |
service.name | Name for the Service, we recommend using kebab-case, for example, my-app. | Yes |
service.port.number | The Service port where the API is reachable. | Yes |
service.openApiSpec.url | URL, pointing to a valid OpenAPI file. The file can be external (hosted anywhere). The Portal must be able to retrieve it without any kind of authentication. | No |
service.openApiSpec.path | YAML and JSON are supported file formats for OpenAPI files. | No |
openApiSpec.operationSets.name | The name of the operationSet used with operationFilter. | No |
openApiSpec.operationSets.matchers | You can also use methods or a combination of a path setting and methods . | No |
openApiSpec.operationSets.matchers.pathPrefix | Defines the path prefix the selected spec operations have to start with. . For example, /customers, /customers/stats . | No |
openApiSpec.operationSets.matchers.pathRegex | Defines the path regex the selected spec operations have to match. For example, /customers/.\*/address . Regular expressions should follow the Golang style. | No |
openApiSpec.operationSets.matchers.methods | Defines a set of HTTP methods of the spec operation to select. For example, ["GET"] or ["GET", "POST"] . | No |
cors.allowCredentials | The header tells browsers whether to expose the response to the frontend JavaScript code when the request's credentials mode (Request.credentials ) is include . Documentation on MDN. | No |
cors.allowOriginList | The header indicates whether the response can be shared with requesting code from the given origin . Documentation on MDN. | No |
cors.allowOriginListRegex | Indicates whether a resource can be shared by returning different values. It allows all origins that contain any match of a regular expression in the Access-Control-Allow-Origin list. Documentation on MDN. | No |
cors.allowHeaders | Used in response to a preflight request which includes the Access-Control-Request-Headers to indicate which HTTP headers can be used during the actual request. Documentation on MDN. | No |
cors.ExposeHeaders | Indicates which headers are safe to expose to the API of a CORS API specification. Documentation on MDN. | No |
cors.allowMethods | HTTP defines a set of request methods to indicate the action to be performed for a given resource. Documentation on MDN. | No |
cors.MaxAge | The header indicates how long the results of a preflight request (that is, the information contained in the Access-Control-Allow-Methods and Access-Control-Allow-Headers headers ) can be cached. Documentation on MDN | No |
headers.request.set | Add custom request headers to an API. | No |
headers.request.delete | Remove a header from an API request. | No |
headers.response.set | Add custom request headers to an API. | No |
headers.response.delete | Remove a header from an API response. | No |
Examples
- Hello API
- OpenAPI & URL
- Operation filtering
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: hello-api # This is the name of your API
namespace: apps
labels: # You can assign any key / value pair for labels
area: customers
module: crm
spec:
pathPrefix: "/customers" # This is the path where your API will be available to consumers
service:
name: hello-service # This is the name of the K8S service that implements the API
port:
number: 3000 # This is the port of the K8S service
openApiSpec:
path: /openapi.yaml # This is the path, within the service, where Hub can find the Open API specification
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: petstore-api
namespace: apps
labels:
area: customers
module: crm
spec:
pathPrefix: "/petstore"
service:
name: petstore-app
port:
number: 3000
openApiSpec:
url: https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.yaml
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
pathPrefix: /api
service:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: pets-operations # Name of the operationSet
matchers:
- path: /pets # The operationSet will be applied to all operations under /pets
name: my-service
port:
number: 8080
CORS
CORS is implemented in web browsers to control and manage how web pages from one domain can interact with resources hosted on another domain.
When a web page loaded from one origin (domain) tries to make a request to a different origin, the browser enforces the same-origin policy by default, which prevents most cross-origin requests.
However, there are valid scenarios where cross-origin communication is necessary, such as fetching data from APIs or loading resources like fonts and scripts from other domains.
CORS allows server owners to specify which origins are permitted to access their resources through HTTP headers.
In Traefik Hub, you can configure the following CORS parameters per API:
Header | Description | Default |
---|---|---|
Access-Control-Allow-Credentials | When set to true, the header tells browsers to expose the response to the frontend JavaScript code. Credentials are cookies, authorization headers, or TLS client certificates. | True |
Access-Control-Allow-Origin | The header is used by servers to inform clients with respect to whether they can share the HTTP response via HTTP requests with another origin. | * |
Access-Control-Allow-Headers | The header indicates which HTTP headers can be used during the actual HTTP request. | * |
HTTP methods | The header indicates what HTTP methods are allowed when accessing resources during a preflight request. | GET , HEAD , POST , PUT , PATCH , DELETE , CONNECT , OPTIONS , TRACE |
According to the CORS specification, you are not allowed to use wildcards and credentials at the same time.
If you tighten Access-Control-Allow-Origin
, make sure you allow the Portal Domain, otherwise, the try-out function will not work in the API Portal.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: customer-api
namespace: apps
labels:
area: customers
module: crm
spec:
pathPrefix: "/customers"
service:
openApiSpec:
path: /openapi.yaml
name: customer-app
port:
number: 3000
cors:
allowCredentials: true
allowOriginList:
- "*"
allowHeaders:
- "Accept"
- "Accept-Language"
- "Content-Language"
- "Content-Type"
- "Authorization"
- "X-TraefikLabs-User"
allowMethods:
- "GET"
- "HEAD"
- "POST"
- "PUT"
- "CONNECT"
- "OPTIONS"
- "TRACE"
Manipulating Headers
In Traefik Hub, you can set and delete headers in the request/response to/from an API.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: customer-api
namespace: apps
labels:
area: customers
module: crm
spec:
pathPrefix: /customers
service:
openApiSpec:
url: /openapi.yam
name: customer-app
port:
number: 3000
headers:
request:
set:
"X-Request-Header": "Custom request header"
"X-Username": "Somebody"
delete:
- "Unnecessary-Request-Header"
response:
set:
"X-Response-Header": "Custom response header"
"X-API-Server": "Traefik Hub"
delete:
- "Secret-Response-Header"
Operation filtering
If you version your APIs with the APIVersion CRD, you only need to configure operation filtering there.
Operation filtering is a way to restrict user groups to a specific set of OpenAPI operations.
Imagine you have an API with the following use case:
- Only members of the
admin
group are allowed to delete customers. - Only members of the
admin
group are allowed to retrieve customer statistics - Members of the
support
group are allowed to retrieve a list with all customers
Configuring operation filtering is done in two steps.
You have to configure operationSets
on your APIs, and reference these in your APIAccess.
OperationSets
An operationSet
consists of the following:
- A name, which will be referenced in the APIAccess.
- A matcher to select the API operation(s) which will be part of the
OperationSet
.
- Path
- Path Prefix
- Path Regex
- Only HTTP Method(s)
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
pathPrefix: /api
service:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: pets-operations # The name of the operationSet.
matchers:
- path: /pets # The matcher path option defines the exact path of the spec operations to select.
name: my-service
port:
number: 8080
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
pathPrefix: /api
service:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: pets-operations # The name of the operationSet.
matchers:
- pathPrefix: /pets # The matcher pathPrefix option defines the path prefix of the spec operations to select.
name: my-service
port:
number: 8080
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
pathPrefix: /api
service:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: pets-operations # The name of the operationSet.
matchers:
- pathRegex: "/customers/.*/address" # The matcher pathRegex option defines the path regex of the matching spec operations to select.
name: my-service
port:
number: 8080
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
pathPrefix: /api
service:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: read-only # The name of the operationSet.
matchers:
methods:
- GET # Two assigned HTTP methods GET and POST.
- POST
name: my-service
port:
number: 8080
- Only one of the following path settings is allowed:
path
,pathPrefix
, orpathRegex
. - You can use the
methods
option without using a path setting (path
,pathPrefix
, orpathRegex
). - It is possible to combine a path setting with the
methods
option. - The
pathRegex
must match both the OpenAPI specification and the request.
For example, the request to/customers/:id
shouldn't be expressed by/customers/[0-9]+
but by/customers/.+
to satisfy both/customers/{flightID}
in the OAS specification and/customers/2
in the actual request made by the user.
Please be aware that the difference between configuring one matcher with multiple options or configuring multiple matchers is subtle.
The examples below show the difference in the syntax.
- One Matcher
- Two Matchers
operationSets:
- name: read-pets
matchers:
- pathPrefix: /pets
methods:
- GET
operationSets:
- name: read-or-path
matchers:
- pathPrefix: /pets
- methods:
- GET
Without a Defined HTTP Method
The following shows an API CRD using an operation matcher with pathPrefix
, without any HTTP method defined.
This allows all operations on the /pets
path prefix.
For example, GET /pets
, GET /pets/{id}
, POST /pets
, PUT /pets/{id}
.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
pathPrefix: /api
service:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: pets-operations
matchers:
- pathPrefix: /pets
name: my-service
port:
number: 8080
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 a matcher with two options, such as pathPrefix
and methods
(acts as a logical AND).
This allows GET
for all operations matching the /pets
path prefix.
For example, GET /pets
, GET /pets/{id}
, GET /pets/findByStatus
.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
pathPrefix: /api
service:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: read-pets
matchers:
- pathPrefix: /pets
methods:
- GET
name: my-service
port:
number: 8080
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 one 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 on the /pets
path prefix.
This allows GET
operations on all endpoints of the API.
For example, GET /pets
, GET /pets/{id}
, GET /pets/findByStatus
, POST /pets
, PUT /pets
, DELETE /pets/{id}
, GET /dogs
, GET /dogs/{id}
.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
pathPrefix: /api
service:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: read-or-path
matchers:
- pathPrefix: /pets
- methods:
- GET
name: my-service
port:
number: 8080
Allow Different Operations for Different Groups
The following example shows an API CRD using four operationSets
to allow different operations for different groups.
path
is used to set the exact path for allowed HTTP methods for the different operationSets
.
These operationSets
are then used by operationFilter
in the APIAccess CRD to configure permissions.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: customer-api
namespace: apps
labels:
area: customers
module: crm
spec:
pathPrefix: "/customers"
service:
name: customer-app
port:
number: 3000
openApiSpec:
path: /customer-spec.yaml
operationSets:
- name: get-customers
matchers:
methods: ["GET"]
path: "/customers"
- name: delete-customers
matchers:
methods: ["DELETE"]
path: "/customers"
- name: cru-resources
matchers:
methods: ["GET","POST","PUT", "PATCH"]
- name: admin-operations
matchers:
pathPrefix: "/admin"