API Gateway using Spring Cloud Gateway


Table of Contents

  1. Introduction to API Gateway
  2. Introduction to Spring Cloud Gateway
  3. Setting Up Spring Cloud Gateway
  4. Creating Routes in Spring Cloud Gateway
  5. Filtering Requests and Responses
  6. Load Balancing and Path Routing
  7. Security in API Gateway
  8. Conclusion

1. Introduction to API Gateway

In a microservices architecture, multiple services work together to provide functionality. However, exposing each service directly to clients can lead to issues such as:

  • Multiple endpoints to manage.
  • High client complexity due to multiple requests to different services.
  • Lack of centralized management for routing and security.

An API Gateway acts as a single entry point for clients, routing requests to the appropriate microservices. It simplifies the management of microservices by handling various concerns, such as:

  • Request routing
  • Load balancing
  • Authentication and authorization
  • Rate limiting
  • Caching
  • Response transformation

The API Gateway pattern is commonly used to aggregate services, ensuring that clients do not need to know the details of the backend services. It allows you to decouple microservices from client applications and provides a clean, unified interface.


2. Introduction to Spring Cloud Gateway

Spring Cloud Gateway is a lightweight, non-blocking API Gateway built on top of Spring WebFlux. It provides an easy way to route requests to microservices, apply filters, and manage cross-cutting concerns such as security, rate limiting, and logging.

Spring Cloud Gateway is highly configurable, supports dynamic routing, and integrates seamlessly with other Spring Cloud services like Eureka for service discovery and Spring Security for securing APIs.

Key Features of Spring Cloud Gateway:

  • Dynamic routing: Routes can be configured based on URL patterns, request parameters, headers, and more.
  • Filters: Allow transformation of requests and responses, providing powerful control over incoming traffic.
  • Load balancing: Built-in support for load balancing via Eureka and Ribbon.
  • Rate limiting: Easy configuration for rate limiting to prevent abuse.
  • Security integration: Easily integrates with Spring Security for authentication and authorization.

3. Setting Up Spring Cloud Gateway

Step 1: Creating a Spring Cloud Gateway Application

To create a Spring Cloud Gateway project, add the necessary dependencies in the pom.xml file:

xmlCopyEdit<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

The spring-cloud-starter-gateway dependency includes everything needed to configure and run Spring Cloud Gateway, while spring-cloud-starter-netflix-eureka-client allows the gateway to integrate with Eureka for service discovery.

Step 2: Configure Application Properties

In application.properties or application.yml, configure the basic setup:

propertiesCopyEditserver.port=8080
spring.application.name=api-gateway
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
  • server.port=8080: The port on which the API Gateway will run.
  • eureka.client.service-url.defaultZone: The URL of the Eureka server to discover microservices.

4. Creating Routes in Spring Cloud Gateway

Step 1: Defining Routes

Routes in Spring Cloud Gateway map client requests to specific backend services. Routes can be defined using the RouteLocatorBuilder in a configuration class.

Here’s an example of how to define a route that forwards requests to a backend microservice:

javaCopyEditpackage com.example.apigateway;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("microservice_route", r -> r.path("/service/**")
                        .uri("http://localhost:8081")) // The URI of the microservice
                .build();
    }
}
  • r.path("/service/**"): Specifies the path pattern that should match the incoming requests.
  • .uri("http://localhost:8081"): The destination URI where the requests should be forwarded (in this case, localhost:8081).

Step 2: Handling Dynamic Routing with Service Discovery

If you’re using Eureka for service discovery, you can dynamically route requests to microservices by using the service name instead of hardcoded URLs. For example:

javaCopyEdit@Bean
public RouteLocator dynamicRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("microservice_route", r -> r.path("/service/**")
                    .uri("lb://MICROSERVICE-DEMO"))  // Using service name with load balancing
            .build();
}

Here, lb://MICROSERVICE-DEMO tells Spring Cloud Gateway to look for the MICROSERVICE-DEMO service in the Eureka registry and use load balancing.


5. Filtering Requests and Responses

Filters allow you to modify requests before they are routed and modify responses before they are returned to the client. There are two types of filters in Spring Cloud Gateway:

  • Global Filters: Apply to all routes.
  • Route-specific Filters: Apply only to a specific route.

Example: Adding Custom Global Filter

javaCopyEditimport org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class CustomGlobalFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("Request Path: " + exchange.getRequest().getPath());
        return chain.filter(exchange);
    }
}

This filter logs the request path for every request that passes through the gateway.

Example: Adding Route-Specific Filter

javaCopyEdit@Bean
public RouteLocator routeWithFilter(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("microservice_route", r -> r.path("/service/**")
                    .filters(f -> f.addRequestHeader("X-Request-Source", "Spring Cloud Gateway"))
                    .uri("http://localhost:8081"))
            .build();
}

This route-specific filter adds a custom header (X-Request-Source) to the request before it is forwarded to the microservice.


6. Load Balancing and Path Routing

Spring Cloud Gateway supports client-side load balancing using Ribbon. This can be enabled by using a service name in the route URI (as shown in the dynamic routing example earlier).

Path Routing

You can route different parts of the URL path to different services. For example, you could route /admin/** to one service and /user/** to another:

javaCopyEdit@Bean
public RouteLocator pathRouting(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("admin_route", r -> r.path("/admin/**")
                    .uri("lb://ADMIN-SERVICE"))
            .route("user_route", r -> r.path("/user/**")
                    .uri("lb://USER-SERVICE"))
            .build();
}

7. Security in API Gateway

Spring Cloud Gateway integrates seamlessly with Spring Security for securing routes. You can apply security measures, such as authentication and authorization, directly within the API Gateway.

Step 1: Basic Authentication Setup

Add the spring-boot-starter-security dependency to your pom.xml file:

xmlCopyEdit<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

You can configure basic authentication in application.properties:

propertiesCopyEditspring.security.user.name=user
spring.security.user.password=password

Step 2: Configuring Security for Routes

You can configure security for specific routes using SecurityWebFilterChain:

javaCopyEditimport org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http.authorizeExchange()
                .pathMatchers("/service/**").authenticated() // Secure specific routes
                .anyExchange().permitAll()
                .and().httpBasic();
        return http.build();
    }
}

This configuration ensures that only authenticated users can access the /service/** routes.


8. Conclusion

In this module, we have covered:

  • Spring Cloud Gateway: How to set up and use Spring Cloud Gateway to route requests to backend microservices.
  • Routing: How to create static and dynamic routes.
  • Filters: How to apply filters to modify requests and responses.
  • Load Balancing: How to enable load balancing with Ribbon and Eureka.
  • Security: How to secure routes using Spring Security.

Spring Cloud Gateway simplifies the process of building a unified API layer in microservices architectures, offering powerful routing, filtering, and security capabilities.