Hemos visto qué es un API Gateway y para qué sirve en una arquitectura de microservicios, cómo el Gateway ayuda a enrutar las peticiones, realizar autenticación/autorization, balancear la carga e incluso proteger el sistema frente a ataques. Ahora toca aplicar la teoría en la práctica y configurar un API Gateway usando Spring Cloud Gateway.
¿Sabías que Netflix fue pionero en desarrollar su propio API Gateway, que inspiró a la industria? Su proyecto Zuul funcionaba tan bien gestionando millones de peticiones por segundo, que el ecosistema Spring creó Spring Cloud Gateway como una alternativa moderna con funcionalidad más amplia.
¿Qué vamos a hacer?
En esta lección configuraremos Spring Cloud Gateway para enrutar peticiones entre varios microservicios. Aprenderás no solo a crear rutas, sino también a usar filtros para ajustar el comportamiento de tu gateway.
1. Preparación del proyecto
Creación de un nuevo proyecto Spring Boot
Empezaremos creando un nuevo proyecto Spring Boot que hará de API Gateway. Para eso puedes usar Spring Initializr o tu herramienta favorita.
Estos son los módulos que necesitaremos:
- Spring Cloud Gateway (obligatorio).
- Spring Boot Web Starter (se añade automáticamente).
- Spring Boot Actuator (para monitorización, opcional).
Configuración del pom.xml o build.gradle
Si usas Maven, añade en tu pom.xml la siguiente dependencia:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
Para usuarios de Gradle, añade en build.gradle:
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
No olvides indicar la versión correcta de Spring Cloud en tu fichero de gestión de versiones. Por ejemplo, si usas Spring Boot versión 3.x, el release compatible de Spring Cloud será 2022.x. Indícalo en la sección de gestión de versiones.
2. Configuración de rutas (Routes)
Una ruta (Route) es el bloque básico en Spring Cloud Gateway. Define a dónde enviar la petición entrante. Empecemos con un ejemplo sencillo: redirigimos todas las peticiones con la ruta /service1/** a un microservicio local corriendo en el puerto 8081.
Configuración en application.yml
Crea el fichero application.yml en la carpeta src/main/resources y añade la configuración mínima:
spring:
cloud:
gateway:
routes:
- id: service1-route
uri: http://localhost:8081
predicates:
- Path=/service1/**
Qué ocurre aquí:
id: identificador único de la ruta.uri: a dónde enviar las peticiones (nuestro microservicio en el puerto8081).predicates: condiciones bajo las cuales se usa la ruta. Aquí indicamos que las peticiones que empiecen por/service1/deben ser manejadas por esta ruta.
Equivalente en código
Si no te va el YAML, otra opción es configurar las rutas directamente en código. Así se podría implementar:
@Bean
public RouteLocator customRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route("service1-route", r -> r.path("/service1/**")
.uri("http://localhost:8081"))
.build();
}
Este método devuelve un RouteLocator que contiene todas las rutas. Fíjate que las rutas se pueden definir con más detalle, añadiendo filtros, de lo que hablaremos más abajo.
Probando la ruta
Arranca tu API Gateway y el microservicio en el puerto 8081. Ahora con Postman, curl o el navegador haz la petición:
GET http://localhost:8080/service1/hello
El API Gateway reenviará la petición al microservicio en http://localhost:8081/hello.
3. Uso de filtros
Los filtros permiten procesar peticiones y respuestas. Es como intervenir en el "proxy" para añadir o modificar información.
Añadiendo filtros
Añadamos un filtro que añada un header HTTP a cada petición. Actualizamos la configuración en application.yml:
spring:
cloud:
gateway:
routes:
- id: service1-route
uri: http://localhost:8081
predicates:
- Path=/service1/**
filters:
- AddRequestHeader=X-Custom-Header, HelloWorld
Ahora cada petición a /service1/ llevará en el header X-Custom-Header: HelloWorld.
Implementación de un filtro custom
También puedes implementar tu propio filtro. Por ejemplo, un filtro que loguee cada petición:
@Component
public class LoggingFilter implements GlobalFilter {
private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
logger.info("Request URI: {}", exchange.getRequest().getURI());
return chain.filter(exchange);
}
}
Ese filtro se ejecutará para cada petición. Si solo lo necesitas para una ruta concreta, puedes añadirlo en la cadena de filtros de esa ruta.
4. Configuración de predicados (Predicates)
Los predicados definen las condiciones bajo las cuales se usará una ruta. Por ejemplo, podemos hacer que la ruta se aplique solo para un método HTTP determinado.
En application.yml añade:
spring:
cloud:
gateway:
routes:
- id: service1-get-route
uri: http://localhost:8081
predicates:
- Path=/service1/**
- Method=GET
Ahora solo las peticiones GET serán enroutadas. Los demás métodos (POST, PUT, etc.) se ignorarán.
Predicados avanzados
Puedes combinar predicados. Por ejemplo, la siguiente configuración manejará solo peticiones con método GET que vengan del host mydomain.com:
predicates:
- Path=/service1/**
- Method=GET
- Host=mydomain.com
5. Filtros y predicados útiles: gestión de CORS
Si tu API Gateway se usa para acceso público, hay que tener en cuenta CORS (Cross-Origin Resource Sharing). Añadamos la siguiente configuración:
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "http://localhost:3000"
allowedMethods:
- GET
- POST
Esta configuración permite peticiones desde el frontend que corre en localhost:3000.
6. Comprobamos el resultado
- Asegúrate de que tus microservicios estén en funcionamiento.
- Abre Postman o usa curl para probar varias rutas:
http://localhost:8080/service1/hello— debería reenviar al microservicio.http://localhost:8080/service1/unknown— debería devolver 404 si el recurso no existe en el microservicio.
Si todo funciona, ¡felicidades! Acabas de crear tu primer API Gateway.
7. Errores típicos y cómo resolverlos
- Error
404al acceder a una ruta: Comprueba que la ruta del predicado coincide con la petición enviada. - Error
500al llamar al microservicio: Asegúrate de que el URI especificado (por ejemplo,http://localhost:8081) está disponible y funcionando. - Problemas de CORS: Si el navegador bloquea las peticiones, verifica que CORS está configurado correctamente.
Más adelante podrás profundizar en configuraciones más complejas del API Gateway, añadiendo autenticación, autorización y balanceo de carga. Enlaces útiles para seguir aprendiendo:
GO TO FULL VERSION