Tutorial: Connect to a managed Gateway for Spring in Azure Container Apps (preview)

Gateway for Spring offers an efficient and powerful way to route, manage and handle API requests as part of a microservices architecture. It serves as an API Gateway that routes external requests to different services, adding various capabilities such as filtering, load balancing, and more. In this article, you learn how to create a gateway that directs requests to your container apps.

In this tutorial, you learn to:

  • Create a Gateway for Spring Java component
  • Update the gateway for spring with custom routes to redirect requests to container apps

Important

This tutorial uses services that can affect your Azure bill. If you decide to follow along step-by-step, make sure you delete the resources featured in this article to avoid unexpected billing.

Prerequisites

Considerations

When running in Gateway for Spring in Azure Container Apps, be aware of the following details:

Item Explanation
Scope The Gateway for Spring runs in the same environment as the connected container app.
Resources The container resource allocation for Gateway for Spring is fixed, the number of the CPU cores is 0.5, and the memory size is 1Gi.
Pricing The Gateway for Spring billing falls under consumption-based pricing. Resources consumed by managed Java components are billed at the active/idle rates. You may delete components that are no longer in use to stop billing.

Setup

Before you begin to work with the Gateway for Spring, you first need to create the required resources.

Execute the following commands to create your resource group and Container Apps environment.

  1. Create variables to support your application configuration. These values are provided for you for the purposes of this lesson. We use the actuator endpoint of admin for spring sample app in this lesson.

    export LOCATION=eastus
    export RESOURCE_GROUP=my-spring-cloud-resource-group
    export ENVIRONMENT=my-spring-cloud-environment
    export JAVA_COMPONENT_NAME=mygateway
    export APP_NAME=myapp
    export IMAGE="mcr.microsoft.com/javacomponents/samples/sample-admin-for-spring-client:latest"
    
    Variable Description
    LOCATION The Azure region location where you create your container app and Java component.
    ENVIRONMENT The Azure Container Apps environment name for your demo application.
    RESOURCE_GROUP The Azure resource group name for your demo application.
    JAVA_COMPONENT_NAME The name of the Java component created for your container app. In this case, you create a Gateway for Spring Java component.
    IMAGE The container image used in your container app.
  2. Log in to Azure with the Azure CLI.

    az login
    
  3. Create a resource group.

    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  4. Create your container apps environment.

    az containerapp env create \
        --name $ENVIRONMENT \
        --resource-group $RESOURCE_GROUP \
        --location $LOCATION
    

    This environment is used to host both the Gateway for Spring component and your container app.

Use the Gateway for Spring Java component

Now that you have a Container Apps environment, you can create your container app use a gateway for spring java components to route request to them.

  1. Create the Gateway for Spring Java component.

    az containerapp env java-component gateway-for-spring create \
        --environment $ENVIRONMENT \
        --resource-group $RESOURCE_GROUP \
        --name $JAVA_COMPONENT_NAME \
    
  2. Create the container app that has the fully qualified domain name (FQDN).

    az containerapp create \
        --name $APP_NAME \
        --resource-group $RESOURCE_GROUP \
        --environment $ENVIRONMENT \
        --image $IMAGE \
        --ingress external \
        --target-port 8080 \
        --query properties.configuration.ingress.fqdn
    

    This command returns the URL of your container app that consumes configuration data. Copy the URL to a text editor so you can use it in next step.

Update the Gateway Routes to route requests

  1. Create a YAML file with the following content. Replace <MYAPP_URL> with the container app FQDN from the previous step.

    springCloudGatewayRoutes:
    - id: "route1"
      uri: "<MYAPP_URL>"
      predicates:
        - "Path=/myapp/{path}"
      filters:
        - "SetPath=/actuator/{path}"
    
  2. Run the following command to update the Gateway for Spring component with your route configuration.

    az containerapp env java-component gateway-for-spring update \
        --environment $ENVIRONMENT \
        --resource-group $RESOURCE_GROUP \
        --name $JAVA_COMPONENT_NAME \ 
        --route-yaml <PTAH_TO_ROUTE_YAML_FILE> \
        --query properties.ingress.fqdn
    

    This command updates the gateway route and returns the URL of your gateway that consumes configuration data.

    The command returns the gateway's URL. Visiting this URL with the path /myapp/health should route the request to your app's actuator/health endpoint, returning {"status":"UP","groups":["liveness","readiness"]}.

Clean up resources

The resources created in this tutorial have an effect on your Azure bill. If you aren't going to use these services long-term, run the following command to remove everything created in this tutorial.

az group delete --resource-group $RESOURCE_GROUP

Route file format

The Gateway for Spring component supports defining routes through properties with ID, URI, predicates, and filters. For more information, see the Spring Cloud Gateway documentation. Following is an example YAML file that demonstrates how to configure these properties.

  springCloudGatewayRoutes:
  - id: "route1"
    uri: "https://otherjavacomponent.myenvironment.test.net"
    predicates:
      - "Path=/v1/{path}"
      - "After=2024-01-01T00:00:00.000-00:00[America/Denver]"
    filters:
      - "SetPath=/{path}"
  - id: "route2"
    uri: "https://otherjavacomponent.myenvironment.test.net"
    predicates:
      - "Path=/v2/{path}"
      - "After=2024-01-01T00:00:00.000-00:00[America/Denver]"
    filters:
      - "SetPath=/{path}"

Allowed configuration list for your Gateway for Spring(#configurable-properties)

The following table describes the gateway component properties you can configure for your app. For more information, see Spring Cloud Gateway Common application properties.

Property name Description Default value
spring.cloud.gateway.default-filters List of filter definitions that are applied to every route.
spring.cloud.gateway.enabled Enables gateway functionality. true
spring.cloud.gateway.fail-on-route-definition-error Option to fail on route definition errors, defaults to true. Otherwise, a warning is logged. true
spring.cloud.gateway.handler-mapping.order The order of RoutePredicateHandlerMapping. 1
spring.cloud.gateway.loadbalancer.use404 false
spring.cloud.gateway.discovery.locator.enabled Flag that enables DiscoveryClient gateway integration. false
spring.cloud.gateway.discovery.locator.filters
spring.cloud.gateway.discovery.locator.include-expression SpEL expression that evaluates whether to include a service in gateway integration or not. The default value is true. true
spring.cloud.gateway.discovery.locator.lower-case-service-id Option to lower case serviceId in predicates and filters. The default value is false. Useful with Eureka when it automatically uppercases serviceId. So, MYSERVICE would match /myservice/** false
spring.cloud.gateway.discovery.locator.predicates
spring.cloud.gateway.discovery.locator.route-id-prefix The prefix for the routeId, defaults to discoveryClient.getClass().getSimpleName() + "_". Service ID is appended to create the routeId.
spring.cloud.gateway.discovery.locator.url-expression SpEL expression that creates the URI for each route. The default value is 'lb://'+serviceId. 'lb://'+serviceId
spring.cloud.gateway.filter.add-request-header.enabled Enables the add-request-header filter. true
spring.cloud.gateway.filter.add-request-parameter.enabled Enables the add-request-parameter filter. true
spring.cloud.gateway.filter.add-response-header.enabled Enables the add-response-header filter. true
spring.cloud.gateway.filter.circuit-breaker.enabled Enables the circuit-breaker filter. true
spring.cloud.gateway.filter.dedupe-response-header.enabled Enables the dedupe-response-header filter. true
spring.cloud.gateway.filter.fallback-headers.enabled Enables the fallback-headers filter. true
spring.cloud.gateway.filter.hystrix.enabled Enables the hystrix filter. true
spring.cloud.gateway.filter.json-to-grpc.enabled Enables the JSON to gRPC filter. true
spring.cloud.gateway.filter.local-response-cache.enabled Enables the local-response-cache filter. false
spring.cloud.gateway.filter.local-response-cache.request.no-cache-strategy
spring.cloud.gateway.filter.local-response-cache.size Maximum size of the cache to evict entries for this route in KB, MB, and GB.
spring.cloud.gateway.filter.local-response-cache.time-to-live Time to expire a cache entry, expressed in s for seconds, m for minutes, and h for hours. 5m
spring.cloud.gateway.filter.map-request-header.enabled Enables the map-request-header filter. true
spring.cloud.gateway.filter.modify-request-body.enabled Enables the modify-request-body filter. true
spring.cloud.gateway.filter.modify-response-body.enabled Enables the modify-response-body filter. true
spring.cloud.gateway.filter.prefix-path.enabled Enables the prefix-path filter. true
spring.cloud.gateway.filter.preserve-host-header.enabled Enables the preserve-host-header filter. true
spring.cloud.gateway.filter.redirect-to.enabled Enables the redirect-to filter. true
spring.cloud.gateway.filter.remove-hop-by-hop.headers
spring.cloud.gateway.filter.remove-hop-by-hop.order 0
spring.cloud.gateway.filter.remove-request-header.enabled Enables the remove-request-header filter. true
spring.cloud.gateway.filter.remove-request-parameter.enabled Enables the remove-request-parameter filter. true
spring.cloud.gateway.filter.remove-response-header.enabled Enables the remove-response-header filter. true
spring.cloud.gateway.filter.request-header-size.enabled Enables the request-header-size filter. true
spring.cloud.gateway.filter.request-header-to-request-uri.enabled Enables the request-header-to-request-uri filter. true
spring.cloud.gateway.filter.request-rate-limiter.default-key-resolver
spring.cloud.gateway.filter.request-rate-limiter.default-rate-limiter
spring.cloud.gateway.filter.request-rate-limiter.enabled Enables the request-rate-limiter filter. true
spring.cloud.gateway.filter.request-size.enabled Enables the request-size filter. true
spring.cloud.gateway.filter.retry.enabled Enables the retry filter. true
spring.cloud.gateway.filter.rewrite-location-response-header.enabled Enables the rewrite-location-response-header filter. true
spring.cloud.gateway.filter.rewrite-location.enabled Enables the rewrite-location filter. true
spring.cloud.gateway.filter.rewrite-path.enabled Enables the rewrite-path filter. true
spring.cloud.gateway.filter.rewrite-request-parameter.enabled Enables the rewrite-request-parameter filter. true
spring.cloud.gateway.filter.rewrite-response-header.enabled Enables the rewrite-response-header filter. true
spring.cloud.gateway.filter.save-session.enabled Enables the save-session filter. true
spring.cloud.gateway.filter.secure-headers.content-security-policy default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
spring.cloud.gateway.filter.secure-headers.content-type-options nosniff
spring.cloud.gateway.filter.secure-headers.disable
spring.cloud.gateway.filter.secure-headers.download-options noopen
spring.cloud.gateway.filter.secure-headers.enabled Enables the secure-headers filter. true
spring.cloud.gateway.filter.secure-headers.frame-options DENY
spring.cloud.gateway.filter.secure-headers.permitted-cross-domain-policies none
spring.cloud.gateway.filter.secure-headers.referrer-policy no-referrer
spring.cloud.gateway.filter.secure-headers.strict-transport-security max-age=631138519
spring.cloud.gateway.filter.secure-headers.xss-protection-header 1 ; mode=block
spring.cloud.gateway.filter.set-path.enabled Enables the set-path filter. true
spring.cloud.gateway.filter.set-request-header.enabled Enables the set-request-header filter. true
spring.cloud.gateway.filter.set-request-host-header.enabled Enables the set-request-host-header filter. true
spring.cloud.gateway.filter.set-response-header.enabled Enables the set-response-header filter. true
spring.cloud.gateway.filter.set-status.enabled Enables the set-status filter. true
spring.cloud.gateway.filter.strip-prefix.enabled Enables the strip-prefix filter. true
spring.cloud.gateway.forwarded.enabled Enables the ForwardedHeadersFilter. true
spring.cloud.gateway.global-filter.adapt-cached-body.enabled Enables the adapt-cached-body global filter. true
spring.cloud.gateway.global-filter.forward-path.enabled Enables the forward-path global filter. true
spring.cloud.gateway.global-filter.forward-routing.enabled Enables the forward-routing global filter. true
spring.cloud.gateway.global-filter.load-balancer-client.enabled Enables the load-balancer-client global filter. true
spring.cloud.gateway.global-filter.local-response-cache.enabled Enables the local-response-cache filter for all routes, which enables you to add a specific configuration at the route level using a LocalResponseCache filter. true
spring.cloud.gateway.global-filter.netty-routing.enabled Enables the netty-routing global filter. true
spring.cloud.gateway.global-filter.netty-write-response.enabled Enables the netty-write-response global filter. true
spring.cloud.gateway.global-filter.reactive-load-balancer-client.enabled Enables the reactive-load-balancer-client global filter. true
spring.cloud.gateway.global-filter.remove-cached-body.enabled Enables the remove-cached-body global filter. true
spring.cloud.gateway.global-filter.route-to-request-url.enabled Enables the route-to-request-url global filter. true
spring.cloud.gateway.global-filter.websocket-routing.enabled Enables the websocket-routing global filter. true
spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping If global CORS config should be added to the URL handler. false
spring.cloud.gateway.globalcors.cors-configurations
spring.cloud.gateway.redis-rate-limiter.burst-capacity-header The name of the header that returns the burst capacity configuration. X-RateLimit-Burst-Capacity
spring.cloud.gateway.redis-rate-limiter.config
spring.cloud.gateway.redis-rate-limiter.include-headers Whether or not to include headers containing rate limiter information. The default value is true. true
spring.cloud.gateway.redis-rate-limiter.remaining-header The name of the header that returns number of remaining requests during the current second. X-RateLimit-Remaining
spring.cloud.gateway.redis-rate-limiter.replenish-rate-header The name of the header that returns the replenish rate configuration. X-RateLimit-Replenish-Rate
spring.cloud.gateway.redis-rate-limiter.requested-tokens-header The name of the header that returns the requested tokens configuration. X-RateLimit-Requested-Tokens
spring.cloud.gateway.restrictive-property-accessor.enabled Restricts method and property access in SpEL. true
spring.cloud.gateway.predicate.after.enabled Enables the after predicate. true
spring.cloud.gateway.predicate.before.enabled Enables the before predicate. true
spring.cloud.gateway.predicate.between.enabled Enables the between predicate. true
spring.cloud.gateway.predicate.cloud-foundry-route-service.enabled Enables the cloud-foundry-route-service predicate. true
spring.cloud.gateway.predicate.cookie.enabled Enables the cookie predicate. true
spring.cloud.gateway.predicate.header.enabled Enables the header predicate. true
spring.cloud.gateway.predicate.host.enabled Enables the host predicate. true
spring.cloud.gateway.predicate.host.include-port Include the port in matching the host name. true
spring.cloud.gateway.predicate.method.enabled Enables the method predicate. true
spring.cloud.gateway.predicate.path.enabled Enables the path predicate. true
spring.cloud.gateway.predicate.query.enabled Enables the query predicate. true
spring.cloud.gateway.predicate.read-body.enabled Enables the read-body predicate. true
spring.cloud.gateway.predicate.remote-addr.enabled Enables the remote-addr predicate. true
spring.cloud.gateway.predicate.weight.enabled Enables the weight predicate. true
spring.cloud.gateway.predicate.xforwarded-remote-addr.enabled Enables the xforwarded-remote-addr predicate. true
spring.cloud.gateway.set-status.original-status-header-name The name of the header which contains the HTTP code of the proxied request.
spring.cloud.gateway.streaming-media-types
spring.cloud.gateway.x-forwarded.enabled If the XForwardedHeadersFilter is enabled. true
spring.cloud.gateway.x-forwarded.for-append If appending X-Forwarded-For as a list is enabled. true
spring.cloud.gateway.x-forwarded.for-enabled If X-Forwarded-For is enabled. true
spring.cloud.gateway.x-forwarded.host-append If appending X-Forwarded-Host as a list is enabled. true
spring.cloud.gateway.x-forwarded.host-enabled If X-Forwarded-Host is enabled. true
spring.cloud.gateway.x-forwarded.order The order of the XForwardedHeadersFilter. 0
spring.cloud.gateway.x-forwarded.port-append If appending X-Forwarded-Port as a list is enabled. true
spring.cloud.gateway.x-forwarded.port-enabled If X-Forwarded-Port is enabled. true
spring.cloud.gateway.x-forwarded.prefix-append If appending X-Forwarded-Prefix as a list is enabled. true
spring.cloud.gateway.x-forwarded.prefix-enabled If X-Forwarded-Prefix is enabled. true
spring.cloud.gateway.x-forwarded.proto-append If appending X-Forwarded-Proto as a list is enabled. true
spring.cloud.gateway.x-forwarded.proto-enabled If X-Forwarded-Proto is enabled. true
spring.cloud.gateway.httpclient.compression Enables compression for Netty HttpClient. false
spring.cloud.gateway.httpclient.connect-timeout The connected timeout in millis. The default value is 30s.
spring.cloud.gateway.httpclient.max-header-size The max response header size.
spring.cloud.gateway.httpclient.max-initial-line-length The max initial line length.
spring.cloud.gateway.httpclient.pool.acquire-timeout Only for type FIXED, the maximum time in millis to wait for acquiring.
spring.cloud.gateway.httpclient.pool.eviction-interval Perform regular eviction checks in the background at a specified interval. Disabled by default ({@link Duration#ZERO}). 0
spring.cloud.gateway.httpclient.pool.max-connections Only for type FIXED, the maximum number of connections before starting pending acquisition on existing ones.
spring.cloud.gateway.httpclient.pool.max-idle-time Time in millis after which the channel is closed. If NULL, there's no max idle time.
spring.cloud.gateway.httpclient.pool.max-life-time Duration after which the channel is closed. If NULL, there's no max life time.
spring.cloud.gateway.httpclient.pool.metrics Enables channel pools metrics to be collected and registered in Micrometer. Disabled by default. false
spring.cloud.gateway.httpclient.pool.name The channel pool map name, defaults to proxy. proxy
spring.cloud.gateway.httpclient.pool.type Type of pool for HttpClient to use, defaults to ELASTIC.
spring.cloud.gateway.httpclient.response-timeout The response timeout.
spring.cloud.gateway.httpclient.ssl.close-notify-flush-timeout SSL close_notify flush timeout. The default value 3000 ms. 3000ms
spring.cloud.gateway.httpclient.ssl.close-notify-read-timeout SSL close_notify read timeout. The default value is 0 ms. 0
spring.cloud.gateway.httpclient.ssl.handshake-timeout SSL handshake timeout. The default value is 10000 ms. 10000ms
spring.cloud.gateway.httpclient.ssl.use-insecure-trust-manager Installs the netty InsecureTrustManagerFactory. This is insecure and isn't suitable for production. false
spring.cloud.gateway.httpclient.websocket.max-frame-payload-length Max frame payload length.
spring.cloud.gateway.httpclient.websocket.proxy-ping Proxy ping frames to downstream services. The default value is true. true
spring.cloud.gateway.httpclient.wiretap Enables wiretap debugging for Netty HttpClient. false
spring.cloud.gateway.httpserver.wiretap Enables wiretap debugging for Netty HttpServer. false
spring.cloud.gateway.metrics.enabled Enables the collection of metrics data. false
spring.cloud.gateway.metrics.prefix The prefix of all metrics emitted by gateway. spring.cloud.gateway
spring.cloud.gateway.metrics.tags Tags map that added to metrics.
spring.cloud.gateway.observability.enabled If Micrometer Observability support should be turned on. true

Common configurations

The following list describes common configurations:

  • Logging related configurations:
    • logging.level.*
    • logging.group.*
    • Any other configurations under logging.* namespace should be forbidden. For example, writing log files by using logging.file should be forbidden.