This topic describes how to add, update, and manage API routes for apps that use a Spring Cloud Gateway for Kubernetes instance.
Spring Cloud Gateway instances match requests to target endpoints using configured API routes. A route is assigned to each request by evaluating a number of conditions, called predicates. Each predicate may be evaluated against request headers and parameter values. All of the predicates associated with a route must evaluate to true for the route to be matched to the request. The route may also include a chain of filters, to modify the request before sending it to the target endpoint, or the received response.
To define the API routes that your service intends to expose for consumers, you must create a SpringCloudGatewayRouteConfig resource. The definition for SpringCloudGatewayRouteConfig specifies:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: # Name given to this route configuration (required)
spec:
service: # Kubernetes Service to route traffic to specified `spec.routes`.
name: # Name of the service, required unless route defines `uri`.
namespace: # (Optional) If not set will use the RouteConfig's namespace.
port: # (Optional) If not set will use one of the available service ports.
predicates: # (Optional) Predicates to be prepended to all routes. See Available Predicates.
filters: # (Optional) Filters to be prepended to all routes. See Available Filters.
ssoEnabled: # (Optional) Define SSO validation for all routes. See "Using Single Sign-On".
routes: # Array of API routes.
- title: # (Optional) A title, will be applied to methods in the generated OpenAPI documentation
description: # (Optional) A description, will be applied to methods in the generated OpenAPI documentation
uri: # (Optional) Full uri, will override `service.name`
ssoEnabled: # Enable SSO validation. See "Using Single Sign-On"
tokenRelay: # Pass currently-authenticated user's identity token to application service
predicates: # See Available Predicates below
filters: # See Available Filters below
order: # Route processing order, same as Spring Cloud Gateway
tags: # Classification tags, will be applied to methods in the generated OpenAPI documentation
basicAuth:
secret: # The secret name containing basic auth credentials.
openapi:
components:
schemas: # Reusable schema objects.
requestBodies: # Reusable request body objects.
Note: service.name is the recommended method for traffic configuration. Use routes.uri only when accessing external resources.
As example, create a file called myapp-route-config.yaml, with the following YAML definition:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: myapp-route-config
spec:
service:
name: myapp
routes:
- predicates:
- Path=/api/public/**
filters:
- StripPrefix=2
To simplify configuration, StripPrefix=1 is applied by default when no value for StripPrefix is set.
In order to avoid repetition across all or most API routes in their route configuration, the following properties can be defined at service level: predicates, filters, and ssoEnabled.
To have certain filters prepended to all routes, you can use the service.filters property. For example, that's how you can add rate limiting to all routes:
spec:
service:
name: myapp
filters:
- RateLimit=2,10s
To have certain predicates prepended to all routes, you can use the service.predicates property. Example of all routes configured with a mandatory header:
spec:
service:
name: myapp
predicates:
- Header=X-Request-Id
To define SSO validation for all routes, you can use the service.ssoEnabled property. Example of all routes configured with SSO:
spec:
service:
name: myapp
ssoEnabled: true
Each route can then override it, as below:
spec:
service:
name: myapp
ssoEnabled: true
routes:
- predicates:
- Path=/api/users
ssoEnabled: false
To add API routes to a Spring Cloud Gateway for Kubernetes instance, you must create a resource of type SpringCloudGatewayMapping that references both a SpringCloudGateway and a SpringCloudGatewayRouteConfig resource. The definition for SpringCloudGatewayMapping specifies:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayMapping
metadata:
name: # Name given to this route mapping (required)
spec:
gatewayRef: # Gateway instance which will serve traffic to the provided route config
name: # Name of the Gateway instance
namespace: # (Optional) If not set will use the Mapping's namespace
routeConfigRef: # Route configuration with the routes to apply to the gateway instance
name: # Name of the route configuration resource
namespace: # (Optional) If not set will use the Mapping's namespace
Continuing the previous example, create a file called myapp-mapping.yaml, with the following YAML definition:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayMapping
metadata:
name: myapp-mapping
spec:
gatewayRef:
name: my-gateway
namespace: my-gateway-ns
routeConfigRef:
name: myapp-route-config
Apply the two definitions to your Kubernetes cluster:
$ kubectl apply -f myapp-route-config.yaml
$ kubectl apply -f myapp-mapping.yaml
Spring Cloud Gateway for Kubernetes processes the two objects and updates the Gateway instance named in the spec.gateway property value (in this example, the my-gateway instance). For the routes configured in the spec.routes section, the Gateway instance will route traffic to the app named in the spec.service property value (in this example, the myapp app).
After creating the mapping and route config resources, you should be able to access the myapp app at the fully qualified domain name (FQDN) used by the Gateway instance and the path /api/*. For example, if your Gateway instance is exposed by an Ingress resource at the domain gateway.example.com, you can access the myapp app at the following URL:
https://gateway.example.com/api/my-path
Note: Application services must respect `X-Forwarded-*` as the API Gateway is acting as a reverse proxy on behalf of the client. For Spring Boot applications, this can be configured by setting `server.forward-headers-strategy=NATIVE`. Please utilize the appropriate approach for your application's programming language and framework.
For more detailed documentation on how to use the OSS Spring Cloud Gateway predicates, see the Spring Cloud Gateway OSS predicates documentation.
| Predicate | Description |
|---|---|
| After | matches requests made after a certain datetime |
| Before | matches requests made before a certain datetime |
| Between | matches requests made between two certain datetimes |
| Cookie | matches requests with a certain cookie |
| Header | matches requests with a certain header |
| Host | matches requests with a certain host pattern |
| Method | matches requests to HTTP method (GET/POST) |
| Path | matches requests with path of certain pattern(s) |
| Query | matches requests with certain query parameter (optional with value pattern) |
| RemoteAddr | matches requests of a certain remote IP address |
| Weight | Split requests between a set of targets in a group |
| JWTClaim | Match on JWT claim value |
For more detailed documentation on how to use the OSS Spring Cloud Gateway filters, see the Spring Cloud Gateway OSS filters documentation. The detailed documentation on additional filters provided by Spring Cloud Gateway for Kubernetes commercial product are listed on the Commercial Route Filters page.
| Filter | Description |
|---|---|
| AddRequestHeader | Adds a header to a request |
| AddRequestHeadersIfNotPresent | Adds headers if not present in the original request |
| AddRequestParameter | Adds a request parameter to a request query string |
| AddResponseHeader | Adds a header to a matching response |
| AllowedRequestCookieCount | Determines if a matching request is allowed to proceed base on number of cookies |
| AllowedRequestHeadersCount | Determines if a matching request is allowed to proceed based on headers |
| AllowedRequestQueryParamsCount | Determines if a matching request is allowed to proceed base on query params |
| ApiKey | validate API keys from X-API-Key header against those stored in Hashicorp Vault |
| BasicAuth | Adds BasicAuth credentials as header |
| CircuitBreaker | Wraps routes in a circuit breaker |
| ClaimHeader | Copies data from a JWT claim into an HTTP Header |
| ClientCertificateHeader | Validate X-Fowarded-Client-Cert header certificate (optional fingerprint) |
| Cors | Configuring per-route Cross-Origin Resource Sharing (CORS) |
| DeDupeResponseHeader | Removes duplicates of certain headers |
| FallbackHeaders | Adds circuit breaker exception to a header |
| GemfireResponseCache | Adds gemfire response cache for specific routes if global cache is enabled |
| JSONToGRPC | Converts a JSON payload to a gRPC request |
| JwtKey | Adds multiple client JWT token validation |
| LocalResponseCache | Adds local response cache for specific routes if global cache is enabled |
| MapRequestHeader | Maps a header from another one |
| PrefixPath | Adds a prefix to a matching request path |
| PreserveHostHeader | Preserves original host header when sending a request |
| RateLimit | Determines if a matching request is allowed to proceed base on volume |
| RedirectTo | Redirects a matching request with certain HTTP code to a certain URL |
| RemoveJsonAttributesResponseBody | Removes JSON attributes and its value from a JSON content |
| RemoveRequestHeader | Removes a header from a matching request |
| RemoveResponseHeader | Removes a header from a response |
| RemoveRequestParameter | Removes a query parameter from a matching request |
| RewriteAllResponseHeaders | Removes a query parameter from a matching request |
| RewritePath | Similar to RewriteResponseHeader, but applies transformation to all headers |
| RewriteLocationResponseHeader | Modifies the value of the location response header |
| RewriteResponseHeader | Rewrite the response header value |
| RewriteResponseBody | Rewrite the response body from a matching request |
| RewriteJsonAttributesResponseBody | Rewrite JSON attributes using JSON Path notations |
| Roles | List authorized roles needed to access route |
| Scopes | List scopes needed to access route |
| SecureHeaders | Adds some headers to a response per a security recommendation |
| SetPath | Manipulates a matching request path |
| SetResponseHeader | Replaces a certain response header |
| SetStatus | Sets HTTP status of a response |
| SSO Login | Redirects to authenticate if no valid Authorization token |
| StoreIpAddress | Store IP address value in the context of the application |
| StoreHeader | Store a header value in the context of the application |
| StripPrefix | Strips parts from a path of a matching request (default: 1) |
| Retry | Retries a matching request |
| RequestSize | Constrains a matching request with a certain request size |
| SetRequestHostHeader | Overrides host header value of a matching request |
| SsoAutoAuthorize | Adds a fake SSO authorization for development purposes |
| TokenRelay | Forwards OAuth2 access token to downstream resources |
OpenApi references can be used by multiple API routes so that they don't have to duplicate definitions in route configuration. It works via the '$ref' property, which targets an object in the openapi section. Currently, this feature is only supported for requests and responses.
In the following example, we're referencing UserRequest and UserResponse objects, which in turn point to schemas.User:
routes:
- predicates:
- Path=/api/users
- Method=POST
model:
requestBody:
content:
'application/json':
schema:
'$ref': "/components/requestBodies/UserRequest"
responses:
'200':
content:
'application/json':
schema:
'$ref': "/components/schemas/UserResponse"
openapi:
components:
schemas:
User:
type: object
properties:
id:
type: string
name:
type: string
email:
type: string
format: email
UserResponse:
'$ref': "/components/schemas/User"
requestBodies:
UserRequest:
required: ["name", "email"]
'$ref': "/components/schemas/User"