Microservices have emerged as a default choice for building scalable, resilient, and maintainable applications. Microservices are best suited for large, complex applications. API Gateway plays a pivotal role in managing and orchestrating communication between microservices within an enterprise. In this article, we will delve into the significance of API Gateway in a microservice architecture and the implementation of API Gateway using Spring Cloud API Gateway.
What is an API gateway?
API Gateway serves as a centralized entry point into your microservice ecosystem. It acts as a mediator between clients and the microservices, providing a unified interface to access them. The API Gateway performs several key functions, including security enforcement, request routing, protocol translation, load balancing, and monitoring of the system.
Why do we need an API gateway?
As the number of microservices within an enterprise grows, so does the complexity of managing communication between them. This is where the API Gateway comes in as a centralized entry point that streamlines and simplifies interactions between microservices. API Gateway significantly reduces the threat to your system by providing a single entry point for your microservice.
API Gateway Features
Below are the key features of an API gateway.
- Centralized entry point: serves as a single entry point for clients to interact with the system.
- Request Routing and Response Composition/aggregation: API Gateway routes the requests to the appropriate microservices based on predefined rules. It can also aggregate data from multiple services to fulfill a client request.
- Protocol Translation: Microservices might use different communication protocols or data formats. API Gateway acts as a translator and translates the requests and responses between different protocols and formats.
- Enhanced security: API Gateway plays a critical role in enforcing security measures such as authentication, authorization, and encryption. It provides a centralized location to implement and manage security policies and protect microservices from unauthorized access.
- Request and Response Transformation: API Gateway can transform requests and responses on demand as per requirements.
- Load Balancing and Traffic Management: API Gateway can implement load-balancing strategies to distribute traffic and prevent overloading individual microservices.
- Monitoring and Usage Analytics: API Gateway tracks metrics, logs, and performance data, offering valuable insights into the health and behavior of the entire system.
Drawbacks of an API Gateway
While API gateways offer significant advantages in managing the microservice architecture, they also come with certain drawbacks that you should consider:
- Single Point of Failure: The API Gateway is a central entry point for all requests, making it a potential single point of failure. If the gateway experiences downtime or breakdown because of any issue, it can disrupt the entire system, impacting the availability of services.
- Increased Latency: Introducing an API Gateway can add latency to requests due to the additional processing, routing, and potential transformations it performs.
- Security Concerns: Although API Gateways enhance security by enforcing policies, they also introduce a single point that, if compromised, could lead to a widespread security breach.
Spring Cloud API Gateway
Spring Cloud Gateway provides an effective way to route to APIs and provides cross-cutting concerns such as security, monitoring/metrics, and resiliency. Spring Cloud Gateway is built on the Spring Framework, Spring Boot, and Project Reactor/Webflux and works on a non-blocking/reactive API model.
Key Features of Spring Cloud Gateway
- Request Routing: Ability to match routes on any request attribute.
- Filtering: Enable you to apply filters specific to routes
- Circuit Breaker Integration: Out-of-the-box integration with the Resilience4j circuit breaker.
- Spring Cloud DiscoveryClient integration
- Easy-to-write Predicates and Filters
- Request Rate Limiting: Apply rate limiting for incoming requests.
- Path Rewriting: Rewrite the path while routing to blackened endpoints.
- WebSocket support
Building blocks of Spring Cloud API Gateway
- Route Configurations: Define routes to map incoming requests to the appropriate microservices. Routes specify the URI path, filters, and target service. Below is the sample configuration:
spring:
cloud:
gateway:
routes:
- id: order-service # Unique id of the route. This must be unique
uri: http://localhost:8081 #Target microservice URI
predicates: # condition that you want to check before routing to the given URI.
- Path=/orders/** # Path predicate for URI path matching
- Route Predicates: Predicates define conditions for route matching based on request attributes such as the URI path, headers, or query parameters. Example:
spring:
cloud:
gateway:
routes:
- id: invoice-service
uri: http://localhost:8081
predicates:
- Path=/invoices/**
- Method=GET
- Global Filters: Configure filters to be applied globally to all routes. These filters are applied to every request that goes through the gateway. Example:
spring:
cloud:
gateway:
globalFilters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
- Gateway Filters: Apply filters to modify requests or responses as they pass through the gateway. Filters can handle tasks such as authentication, authorization, logging, and more.
spring:
cloud:
gateway:
routes:
- id: order-service
uri: http://localhost:8081
predicates:
- Path=/orders/** # Path predicate for URI path matching
filters:
- StripPrefix=1 # Remove the first segment of the path
Building an API Gateway in Java using Spring Cloud API Gateway.
Let us initialize the project from Spring Initializer and add the “Reactive Gateway” dependency as shown below.
Gradle Configuration:
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.techmonks'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "2023.0.0")
}
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}
application.yml configuration
spring:
cloud:
gateway:
routes:
- id: order-service
uri: http://localhost:8081
predicates:
- Path=/orders/** # Path predicate for URI path matching
Create Custom Global Filters
Let us create a simple global filter that intercepts the requests and responses and logs them into the console.
package com.techmonks.apigateway.filters;
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;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
@Component
public class RequestAndResponseLogGlobalFilter implements GlobalFilter, Ordered {
private static final Logger logger = LogManager.getLogger(RequestAndResponseLogGlobalFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
logger.info("Pre Filter Logic: Request path: {}", exchange.getRequest().getPath().toString());
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
logger.info("Post Filter Logic: HTTP Status Code: {}", exchange.getResponse().getStatusCode().toString());
}));
}
@Override
public int getOrder() {
return -1;
}
}
Now, let us run the application and verify the logs.
As always, you can find the complete source code on GitHub.
Conclusion
In the ever-evolving landscape of enterprise software development, microservices architecture has become a cornerstone for building robust and scalable systems. As a central component of this architecture, the API Gateway plays a pivotal role in simplifying communication, enhancing security, and ensuring the overall efficiency of a microservices-based ecosystem. As enterprises continue to adopt and embrace microservices, the strategic implementation of a robust API gateway becomes paramount for achieving the full potential of this architectural paradigm.
That’s all for today!
Thank you for taking the time to read this article. I hope you have enjoyed it. If you enjoyed it and would like to stay updated on various technology topics, please consider subscribing for more insightful content.
References: