Spring Cloud Gateway: Basic Example

Published: (December 30, 2025 at 01:03 PM EST)
5 min read
Source: Dev.to

Source: Dev.to

Cover image for Spring Cloud Gateway: Basic Example

Eduardo

Spring Cloud Gateway (also known as a gateway or Edge Service) is a dynamic routing server. In other words, it allows us to have a centralized access point to our microservices. Additionally, we can extend its functionality by adding filters or predicates, among other things.

1. Spring Cloud Gateway Configuration

Create a project using Spring Initializr (or your favorite IDE) and make sure to select the following dependencies:

  • Eureka Discovery Client
  • Gateway

The project will also be registered by Eureka Server, so add the following configuration:

@EnableEurekaClient
@SpringBootApplication
public class EurekaClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaClientApplication.class, args);
    }
}

Application properties (YAML)

spring:
  application:
    name: gateway-server-service
server:
  port: 8090
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

2. Routes

The minimum essential configuration for the Edge/Gateway is the routes. These routes redirect requests from the gateway to the service that will answer the request.

Basic route configuration (YAML)

spring:
  cloud:
    gateway:
      routes:
        - id: employees
          uri: lb://employees
          predicates:
            - Path=/api/employees/**
          filters:
            - StripPrefix=2

Explanation

ElementDescription
idUnique identifier of the route.
uriAddress where the gateway will look for the service to redirect. It must start with lb (Load Balancer) when using service discovery like Eureka.
predicatesRules that must be met for the redirection.
filtersOperations that manipulate the request/response passing through the declared route.

In the example above, the gateway routes to a microservice called employees. To get a response from it, you call the Spring Cloud Gateway on the gateway’s port (8090) instead of the microservice’s port directly.

2.1 Predicates

Predicates are a list of rules that must be satisfied for the redirection to succeed. They can be based on path, header, HTTP method, query parameter, or cookie.

Examples

predicates:
  - Path=/api/products/**
  - Header=token, \d+
  - Method=GET, POST
  - Query=color
  - Cookie=color, blue

Meaning

PredicateDescription
PathRedirects requests that match the declared path.
HeaderChecks that the specified header is present with a value that matches the given regular expression.
MethodAllows only the listed HTTP methods.
QueryRequires the given query parameter to be present in the URL.
CookieChecks that the specified cookie exists (and optionally matches a value).

2.2 Spring Cloud Gateway Factory Filters

Factory filters let you manipulate the request and response (e.g., add headers or request parameters).

Configuration (YAML)

filters:
  - AddRequestHeader=token-request, 123456
  - AddResponseHeader=token-response, 12345678
  - SetResponseHeader=Content-Type, text/plain
  - AddRequestParameter=name, andres

These filters are applied only to the route where they are declared.

2.3 Spring Cloud Gateway Global Filters

Global filters are applied to all requests passing through the gateway, without needing to declare them per‑route.

Example implementation

package com.funcionaenmimaquina.springboot.app.gateway.filters;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class ExampleGlobalFilter implements GlobalFilter, Ordered {

    private final Logger logger = LoggerFactory.getLogger(ExampleGlobalFilter.class);

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info("Executing request filter");

        // Modifying the request
        exchange.getRequest()
                .mutate()
                .header("environment", "dev")
                .build();

        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            logger.info("Executing response filter");
            // Adding a cookie to the response
            exchange.getResponse()
                    .addCookie(ResponseCookie.from("myCookie", "myValue")
                            .path("/")
                            .maxAge(3600)
                            .build());
        }));
    }

    @Override
    public int getOrder() {
        // Lower values have higher precedence
        return -1;
    }
}

In this example, the filter adds an environment header to every incoming request and a cookie named myCookie to every response.

Global Filter Example (continued)

o("Executing response filter");

// Modifying the response
Optional.ofNullable(exchange.getRequest().getHeaders().getFirst("environment"))
        .ifPresent(value -> {
            exchange.getResponse().getHeaders().add("env", value);
        });

exchange.getResponse().getHeaders().setContentType(MediaType.TEXT_PLAIN);
}))
;

@Override
public int getOrder() {
    return 1;
}
}

How the example works

  • Implements the GlobalFilter and Ordered interfaces.
  • getOrder defines the execution order when multiple global filters are present.
  • The filter method contains all logic that interacts with the request and response.
  • Line 24 shows where you can manipulate the request (e.g., adding a header).
  • Line 27 shows how to manipulate the response using .then(Mono.fromRunnable(...)).
  • Line 31 adds a header to the response if a specific request header exists.
  • Line 34 forces the response to use plain‑text (text/plain) media type.

2.4 Filter Factory (Custom Gateway Filter)

If you want a filter to apply only to selected routes, create a custom filter factory:

@Component
public class ExampleGatewayFilterFactory
        extends AbstractGatewayFilterFactory {

    private final Logger logger = LoggerFactory.getLogger(ExampleGatewayFilterFactory.class);

    public ExampleGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            logger.info("Zone to modify the request");

            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                logger.info("Zone to modify the response");

                Optional.ofNullable(config.cookieValue).ifPresent(cookieVal -> {
                    exchange.getResponse()
                            .addCookie(ResponseCookie.from(config.cookieName, cookieVal).build());
                });
            }));
        };
    }

    @Override
    public String name() {
        return "ExampleCookie";
    }

    @Override
    public List shortcutFieldOrder() {
        return Arrays.asList("cookieName", "cookieValue");
    }

    public static class Config {
        private String cookieName;
        private String cookieValue;

        // Getters and Setters
        public String getCookieValue() { return cookieValue; }
        public void setCookieValue(String cookieValue) { this.cookieValue = cookieValue; }
        public String getCookieName() { return cookieName; }
        public void setCookieName(String cookieName) { this.cookieName = cookieName; }
    }
}

Usage in application.yml

filters:
  - StripPrefix=2
  - ExampleCookie=user, myName

What the code does

  • Adds a cookie to the response using the values defined in the YAML file.

Conventions & requirements

  1. The class name must end with FilterFactory.
  2. It extends AbstractGatewayFilterFactory.
  3. An inner Config class stores values supplied from the YAML file.
  4. The filter logic resides in the apply method.
  5. The name() method’s return value must match the key used in the YAML (or default to the class‑name prefix).
  6. shortcutFieldOrder defines the order in which the short‑notation values are mapped to the configuration fields.

Only the routes that reference this filter in application.yml will have it applied.

Conclusions

You now understand:

  • What Spring Cloud Gateway is and the problems it solves.
  • How to configure predicates and filters to extend its functionality.
  • How to create global filters and custom filter factories for fine‑grained control.

Practice building and customizing gateways to become comfortable using them in real‑world projects.

Back to Blog

Related posts

Read more »

Spring Cloud 마이크로서비스 - Eureka와 Multi-Module 프로젝트

마이크로서비스와 Spring Cloud 마이크로서비스 아키텍처는 대규모 애플리케이션을 작은 서비스 단위로 분리하여 독립적으로 개발, 배포, 확장할 수 있게 합니다. Spring Cloud는 이러한 마이크로서비스 구축을 위한 다양한 도구를 제공합니다. Eureka는 Netflix OSS...