Spring Cloud Gateway for Kubernetes 2.2

Access OpenAPI-generated documentation for SCG for K8s

Last Updated March 10, 2025

Here are instructions for providing API Gateway metadata and explaining how API route configurations are used to auto-generate OpenAPI v3 documentation.

Accessing generated OpenAPI v3 documentation

The Spring Cloud Gateway for Kubernetes operator manages all API Gateway instances on the Kubernetes cluster. When you apply any SpringCloudGateway, SpringCloudGatewayRouteConfig or SpringCloudGatewayMapping custom resources onto the Kubernetes cluster, the operator will act to reconcile the environment with those request resource changes.

In addition to handling custom resource reconciliation, the operator also has an OpenAPI v3-compliant auto-generated documentation endpoint. You can access this endpoint by exposing the scg-operator service with an ingress and then access its /openapi endpoint.

An example ingress applied to the scg-operator service in the spring-cloud-gateway namespace is shown below:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: scg-openapi
  namespace: spring-cloud-gateway
  annotations:
    kubernetes.io/ingress.class: contour
spec:
  rules:
  - host: scg-openapi.mydomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: scg-operator
            port:
              number: 80

Now you can access the auto-generated OpenAPI v3 endpoint by going to https://scg-openapi.mydomain.com/openapi.

Application developers provide API route configurations to be dynamically exposed on an API Gateway instance and those API routes will then be input for generated documentation. This leads to consistent APIs based on API route configuration predicates, filters and metadata across all service instances and the APIs they expose.

It is important to note that by default a separate OpenAPI v3 document will be generated for each API Gateway instance and the /openapi endpoint provides an array of these documents for all of the instances on this Kubernetes cluster.

There are options to limit the documents that are returned by using path or query parameters to the /openapi endpoint.

Using path parameters

If you want to limit the results to only API documents for gateways in a particular namespace, you can use that namespace as a path parameter.

For example, to get an array of API documents for gateways in the namespace my-namespace you would use a URL like the following:

https://scg-openapi.mydomain.com/openapi/my-namspace

If you want to limit the results to return a single API document you can use both the namespace and name of that gateway as path parameters. For example, to get an single API document for a gateway in namespace my-namspace named my-gateway you could use a URL like the following:

https://scg-openapi.mydomain.com/openapi/my-namspace/my-gateway

This returns a single document and not an array.

Using query parameters

Another way to limit results is by based on the group and/or version of the gateways whose values can be found in spec.api.groupId and spec.api.version respectively.

For instance, if you wanted to only get API documents for gateways with version 0.0.1 you could use a URL as in the following example:

https://scg-openapi.mydomain.com/openapi?version=0.0.1

If you wanted to only get API documents for gateways that had a group id of of `accounting’ you could use a URL as in the following example:

https://scg-openapi.mydomain.com/openapi?groupId=accounting

You can also combine both the groupId and version query parameters. For instance, if you wanted to get the API specification documents for API gateways with a groupId of accounting having a version of 0.0.1 you could construct a URL as shown in the following example:

https://scg-openapi.mydomain.com/openapi?groupId=accounting&version=0.0.1

Remove API routes from auto-generated OpenAPI specification

By default, the OpenAPI specification is generated for all the routes currently applied. You can remove a route from the OpenAPI generation process marking openapi.generation.enabled = false.

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
  name: myapp-route-config
spec:
  service:
    name: myapp-service
  routes:
    - id: route-without-openapi
      openapi:
        generation:
          enabled: false
      predicates:
        - Path=/users/**

Or, you can drop all the routes in the OpenAPI specification using spec.openapi.generation.enabled = false.

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
  name: myapp-route-config
spec:
  service:
    name: myapp-service
  openapi:
    generation:
      enabled: false
  routes:
    - id: route-1-without-openapi
      predicates:
        - Path=/users/**
    - id: route-2-without-openapi
      predicates:
        - Path=/users/**

Additionally, both options can be used together to turn off OpenAPI generation for all the routes and activate it on specific routes

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
  name: myapp-route-config
spec:
  service:
    name: myapp-service
  openapi:
    generation:
      enabled: false
  routes:
    - id: route-1-without-openapi
      predicates:
        - Path=/users/**
    - id: route-2-with-openapi
      openapi:
        generation:
          enabled: true
      predicates:
        - Path=/users/**

Configure OpenAPI metadata

The following descriptive metadata can be defined when configuring an API Gateway instance:

  • serverUrl: Publicly accessible user-facing URL of this Gateway instance. It is important to note that this configuration does not create a new route mapping for this URL, this is only for metadata purposes to display in the OpenAPI generated documentation.
  • title: Title describing the context of the APIs available on the Gateway instance (default: name of the Gateway instance)
  • description: Detailed description of the APIs available on the Gateway instance (default: Generated OpenAPI 3 document that describes the API routes configured for '[Gateway instance name]' Spring Cloud Gateway instance deployed under '[namespace]' namespace.)
  • version: Version of APIs available on this Gateway instance (default: unspecified)
  • documentation: Location of additional documentation for the APIs available on the Gateway instance
  • CORS: Configuration to avoid Cross-Origin Resource Sharing related problems, we recommend setting allowedOrigins and allowedMethods properties, check out the full CORS guide.

Here is an example of an API Gateway configuration using this descriptive metadata and annotations:

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: my-gateway
  annotations:
    apis.tanzu.vmware.com/api-title: 'My Exciting APIs'
    apis.tanzu.vmware.com/api-description: 'Lots of new exciting APIs for you to use!'
    apis.tanzu.vmware.com/api-documentation: 'https://docs.example.org'
spec:
  api:
    serverUrl: https://gateway.example.org
    version: 0.1.0
  cors:
    allowedOrigins:
      - "https://foo.example.com"
    allowedMethods:
      - "GET"

This will be displayed in the /openapi endpoint of the operator as:

"info": {
  "title": "My Exciting APIs",
  "description": "Lots of new exciting APIs that you can use for examples!",
  "version": "0.1.0"
},
"externalDocs": {
  "url": "https://docs.example.org"
},
"servers": [
  {
    "url": "https://gateway.example.org"
  }
],

Configuration via spec.api is still supported in v2.1, but it is considered deprecated and will be removed in future versions. Using annotations is the preferred method.

spec:
  api:
    serverUrl: https://gateway.example.org
    title: My Exciting APIs
    description: Lots of new exciting APIs that you can use for examples!
    version: 0.1.0
    documentation: https://docs.example.org

PUT/POST/PATCH request body schema

For PUT, POST and PATCH operations, you may add the OpenAPI Schema of Request Body objects.

As in the example below, add model.requestBody property to a route with the proper information.

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
  name: myapp-route-config
spec:
  service:
    name: myapp-service
  routes:
    - id: example-route-id
      predicates:
        - Path=/users/**
      model:
        requestBody:
          description: User to add
          content:
            'application/json':
              schema:
                type: object
                description: User schema
                properties:
                  name:
                    type: string
                  age:
                    type: integer
                    format: int32
                required:
                  - name

The model, alongside with the available HTTP methods and headers will be published under paths.

"paths": {
    "/users/**": {
        "summary": "example-route-id",
        "get": {
            "responses": {
                "200": {
                    "description": "Ok"
                }
            }
        },
        "post": {
            "requestBody": {
                "description": "User to add",
                "content": {
                    "application/json": {
                        "schema": {
                            "required": [
                                "name"
                            ],
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string"
                                },
                                "age": {
                                    "type": "integer",
                                    "format": "int32"
                                }
                            },
                            "description": "User schema"
                        }
                    }
                }
            },
            "responses": {
                "200": {
                    "description": "Ok"
                }
            }
        }

Custom HTTP responses

In order to add custom HTTP responses for your paths, you may add the OpenAPI Schema of Responses objects.

As in the example below, add model.responses property to a route with the proper information.

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
  name: myapp-route-config
spec:
  service:
    name: myapp-service
  routes:
    - id: example-route-id
      predicates:
        - Path=/users/**
      model:
        responses:
          200:
            description: "Obtain a list of users"
            content:
              application/json:
                schema:
                  type: object
                  description: User schema
                  properties:
                    name:
                      type: string
                    age:
                      type: integer
                      format: int32
          3XX:
            description: "Redirection applied"
            headers:
              X-Redirected-From:
                schema:
                  type: string
                  description: URL from which the request was redirected.
          default:
            description: "Unexpected error"

If you don’t provide any HTTP responses, the operator will generate by default a 200 Ok response for every path’s operation. Some filters may add custom responses as well to document their inner functionality. You can overwrite these responses too by including them in this section.