Spring Cloud Gateway para enrutado

Intermedio
SpringBoot
SpringBoot
Actualizado: 09/10/2025

Configuración de proyecto con Spring Gateway

Spring Cloud Gateway ha evolucionado considerablemente desde sus primeras versiones. Inicialmente, esta tecnología se basaba exclusivamente en el stack reactivo de Spring WebFlux, lo que requería familiarizarse con programación reactiva para implementar un gateway. Sin embargo, las versiones modernas ofrecen una alternativa basada en el stack servlet tradicional, facilitando su adopción para desarrolladores que ya conocen Spring MVC.

Stack reactivo vs stack servlet

Stack reactivo, usando webflux:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway-server-webflux</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

Stack MVC basado en servlet, el tradicional, sin usar programación reactiva:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway-server-webmvc</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

Configuración inicial del proyecto

Para crear un proyecto Spring Cloud Gateway con el stack servlet, comenzamos con un proyecto Spring Boot estándar. La estructura del pom.xml debe incluir las dependencias fundamentales:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.5.6</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<scm>
		<connection/>
		<developerConnection/>
		<tag/>
		<url/>
	</scm>
	<properties>
		<java.version>17</java.version>
		<spring-cloud.version>2025.0.0</spring-cloud.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-gateway-server-webmvc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Configuración básica del Gateway

La configuración del gateway se realiza principalmente a través del archivo application.yml

En la propia aplicación gateway lo que hacemos es conectar al config server que será el que nos proporcione la configuración centralizada:

spring:
    cloud:
        config:
            uri: http://localhost:8888
    application:
        name: gateway

Y por tanto en el repositorio git donde están todos los archivos de configuración habrá que crear uno para el gateway:

Esta configuración define el comportamiento básico del gateway sin necesidad de código Java adicional, con ejemplo de cómo configurar aplicaciones microservicios para enrutarlas:

server:
  port: 8080

eureka:
    client:
        serviceUrl:
            defaultZone: "http://${app.eureka-server}:8761/eureka/"

        initialInstanceInfoReplicationIntervalSeconds: 5
        registryFetchIntervalSeconds: 5
    instance:
      leaseRenewalIntervalInSeconds: 5
      leaseExpirationDurationInSeconds: 5

spring:
  cloud:
    gateway:
      routes:
        # MICROSERVICIO customers
        - id: customers
          uri: lb://customers
          predicates:
            - Path=/customers/**
        # MICROSERVICIO directions
        - id: directions
          uri: lb://directions
          predicates:
            - Path=/directions/**

        # Eureka
        - id: eureka-api
          uri: http://localhost:8761
          predicates:
            - Path=/eureka/api/{segment}
          filters:
            - SetPath=/eureka/{segment}

        - id: eureka-web-start
          uri: http://localhost:8761
          predicates:
            - Path=/eureka/web
          filters:
            - SetPath=/

        - id: eureka-web-other
          uri: http://localhost:8761
          predicates:
            - Path=/eureka/**

Clase principal de la aplicación

La clase principal del gateway es una aplicación Spring Boot estándar. No requiere anotaciones especiales para el gateway MVC, aunque sí necesitamos habilitar el cliente Eureka:

package com.ejemplo.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

Verificación de la configuración

Una vez configurado el proyecto, podemos verificar que el gateway arranca correctamente. Al ejecutar la aplicación, deberíamos ver en los logs:

INFO  --- [  main] c.ejemplo.gateway.ApiGatewayApplication : Started ApiGatewayApplication in 3.245 seconds
INFO  --- [  main] o.s.c.g.m.GatewayMvcConfiguration        : Gateway MVC enabled

El gateway estará disponible en http://localhost:8080 y se registrará automáticamente en Eureka Server si está ejecutándose en http://localhost:8761.

Diferencias clave del stack MVC

Al utilizar el stack servlet, obtenemos varias ventajas importantes:

  • Compatibilidad total con Spring MVC y sus anotaciones familiares
  • Debugging más sencillo al usar el modelo de threading tradicional
  • Integración directa con herramientas existentes de Spring Boot
  • Curva de aprendizaje reducida para desarrolladores que conocen Spring MVC

La principal diferencia técnica es que el gateway MVC procesa las peticiones de forma síncrona utilizando el modelo de threading tradicional de Tomcat, mientras que la versión reactiva utiliza un modelo asíncrono basado en Netty.

Esta configuración inicial nos proporciona la base sólida necesaria para implementar rutas, predicados y filtros en nuestro gateway, aprovechando toda la potencia de Spring Cloud Gateway sin la complejidad adicional de la programación reactiva.

No obstante, en la actualidad es habitual utilizar webflux con todo el stack reactivo ya que ofrece un sistema no bloqueante ideal para escalar aplicaciones de alto rendimiento.

Rutas y predicados (Path, Method)

Las rutas en Spring Cloud Gateway definen cómo se dirigen las peticiones entrantes hacia los servicios backend correspondientes. Cada ruta combina uno o varios predicados que determinan si una petición coincide con esa ruta específica, junto con filtros que pueden modificar la petición o respuesta.

Conceptos fundamentales

Un predicado actúa como una condición que debe cumplirse para que una petición sea procesada por una ruta determinada. Spring Cloud Gateway MVC ofrece múltiples tipos de predicados, siendo los más utilizados Path y Method, que permiten enrutar basándose en la URL y el método HTTP respectivamente.

La definición de rutas se realiza principalmente mediante configuración declarativa en el archivo application.yml, aunque también es posible definirlas programáticamente mediante código Java.

Configuración de rutas con predicado Path

El predicado Path permite enrutar peticiones basándose en el patrón de la URL. Este predicado utiliza la sintaxis de Spring PathMatcher, que incluye soporte para comodines y variables de ruta.

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: usuarios-service
            uri: http://localhost:8081
            predicates:
              - Path=/api/usuarios/**
              
          - id: productos-service
            uri: http://localhost:8082
            predicates:
              - Path=/api/productos/**
              
          - id: pedidos-service
            uri: http://localhost:8083
            predicates:
              - Path=/api/pedidos/**

En este ejemplo, cualquier petición que comience con /api/usuarios/ será enrutada hacia el servicio ejecutándose en el puerto 8081. El patrón /** indica que coincide con cualquier sub-ruta después del prefijo especificado.

Patrones avanzados con Path

El predicado Path soporta patrones más específicos utilizando variables y expresiones regulares:

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: usuario-por-id
            uri: http://localhost:8081
            predicates:
              - Path=/api/usuarios/{id}
              
          - id: productos-por-categoria
            uri: http://localhost:8082
            predicates:
              - Path=/api/productos/categoria/{categoria}/**
              
          - id: busqueda-flexible
            uri: http://localhost:8083
            predicates:
              - Path=/api/search/{tipo:[a-z]+}

Las variables de ruta como {id} y {categoria} se capturan automáticamente y pueden ser utilizadas por filtros posteriores. La expresión {tipo:[a-z]+} utiliza una expresión regular para validar que el parámetro tipo contenga únicamente letras minúsculas.

Configuración de rutas con predicado Method

El predicado Method filtra peticiones basándose en el método HTTP utilizado. Es especialmente útil cuando queremos que diferentes métodos HTTP sean manejados por servicios distintos o requieran tratamientos diferenciados.

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: usuarios-lectura
            uri: http://localhost:8081
            predicates:
              - Path=/api/usuarios/**
              - Method=GET
              
          - id: usuarios-escritura
            uri: http://localhost:8082
            predicates:
              - Path=/api/usuarios/**
              - Method=POST,PUT,DELETE

En este caso, las peticiones GET a /api/usuarios/** se dirigen al servicio de solo lectura en el puerto 8081, mientras que las operaciones de escritura (POST, PUT, DELETE) se enrutan al servicio especializado en escrituras en el puerto 8082.

Combinación de múltiples predicados

Los predicados pueden combinarse para crear condiciones más específicas. Cuando se especifican múltiples predicados para una ruta, todos deben cumplirse para que la petición coincida:

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: api-admin
            uri: http://localhost:8084
            predicates:
              - Path=/api/admin/**
              - Method=POST,PUT,DELETE
              
          - id: api-publica
            uri: http://localhost:8085
            predicates:
              - Path=/api/public/**
              - Method=GET
              
          - id: reportes-especificos
            uri: http://localhost:8086
            predicates:
              - Path=/api/reportes/{tipo}
              - Method=GET

Integración con Eureka Service Discovery

Una de las ventajas principales del gateway es su integración con Eureka para service discovery. En lugar de especificar URIs estáticas, podemos referenciar servicios por su nombre registrado en Eureka:

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: usuarios-service
            uri: lb://USUARIOS-SERVICE
            predicates:
              - Path=/api/usuarios/**
              
          - id: productos-service
            uri: lb://PRODUCTOS-SERVICE
            predicates:
              - Path=/api/productos/**
              - Method=GET,POST
              
          - id: inventario-service
            uri: lb://INVENTARIO-SERVICE
            predicates:
              - Path=/api/inventario/**
              - Method=GET,PUT

El prefijo lb:// indica a Spring Cloud Gateway que debe utilizar el LoadBalancer para resolver el nombre del servicio. USUARIOS-SERVICE debe coincidir con el nombre registrado en Eureka Server.

Configuración programática de rutas

Además de la configuración YAML, es posible definir rutas programáticamente mediante beans de configuración:

@Configuration
public class GatewayConfig {
    
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("usuarios-api", r -> r
                .path("/api/usuarios/**")
                .and()
                .method(HttpMethod.GET, HttpMethod.POST)
                .uri("lb://USUARIOS-SERVICE")
            )
            .route("productos-especificos", r -> r
                .path("/api/productos/{categoria}")
                .and()
                .method(HttpMethod.GET)
                .uri("lb://PRODUCTOS-SERVICE")
            )
            .build();
    }
}

Esta aproximación programática ofrece mayor flexibilidad para lógica compleja de enrutado, aunque para la mayoría de casos la configuración declarativa en YAML resulta más clara y mantenible.

Precedencia y orden de evaluación

Cuando múltiples rutas pueden coincidir con una petición, Spring Cloud Gateway evalúa las rutas en el orden definido en la configuración. La primera ruta que coincida será la utilizada:

spring:
  cloud:
    gateway:
      mvc:
        routes:
          # Ruta más específica - se evalúa primero
          - id: usuarios-admin
            uri: lb://USUARIOS-ADMIN-SERVICE
            predicates:
              - Path=/api/usuarios/admin/**
              - Method=POST,PUT,DELETE
              
          # Ruta más general - se evalúa después
          - id: usuarios-general
            uri: lb://USUARIOS-SERVICE
            predicates:
              - Path=/api/usuarios/**

Es fundamental colocar las rutas más específicas antes que las generales para evitar que peticiones sean capturadas por rutas demasiado amplias.

Debugging y monitorización de rutas

Para facilitar el desarrollo y depuración, podemos habilitar logging detallado que nos muestre qué rutas se están evaluando:

logging:
  level:
    org.springframework.cloud.gateway.mvc: DEBUG
    org.springframework.web.servlet.mvc.method.annotation: DEBUG

Con este logging activado, podremos observar en los logs cómo cada petición es evaluada contra los predicados definidos, facilitando la identificación de problemas de configuración o comportamientos inesperados en el enrutado.

Filtros básicos y reescritura de paths

Los filtros en Spring Cloud Gateway permiten modificar las peticiones entrantes y las respuestas salientes de forma transparente. Actúan como middleware que se ejecuta antes o después del enrutado hacia los servicios backend, proporcionando funcionalidades como transformación de URLs, adición de headers, autenticación y logging.

Tipos de filtros

Spring Cloud Gateway MVC ofrece dos categorías principales de filtros:

  • Filtros globales: Se aplican a todas las rutas configuradas en el gateway
  • Filtros específicos de ruta: Se aplican únicamente a rutas individuales

Los filtros se ejecutan en un orden determinado, permitiendo crear cadenas de procesamiento que transforman gradualmente las peticiones y respuestas.

Filtros globales básicos

Los filtros globales se configuran en la sección default-filters y afectan a todas las rutas del gateway:

spring:
  cloud:
    gateway:
      mvc:
        default-filters:
          - AddRequestHeader=X-Gateway-Source, api-gateway
          - AddResponseHeader=X-Powered-By, Spring-Cloud-Gateway
          - RemoveRequestHeader=X-Internal-Auth
          - RemoveResponseHeader=Server

Este ejemplo añade headers informativos tanto a peticiones como respuestas, y elimina headers que no queremos exponer externamente.

Reescritura de paths con RewritePath

El filtro RewritePath es uno de los más utilizados, ya que permite modificar la URL antes de enviarla al servicio backend. Utiliza expresiones regulares para capturar partes de la URL original y recomponerla:

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: usuarios-v1
            uri: lb://USUARIOS-SERVICE
            predicates:
              - Path=/v1/usuarios/**
            filters:
              - RewritePath=/v1/usuarios/(?<segment>.*), /api/users/$\{segment}
              
          - id: productos-legacy
            uri: lb://PRODUCTOS-SERVICE
            predicates:
              - Path=/legacy/productos/**
            filters:
              - RewritePath=/legacy/productos/(?<remaining>.*), /api/v2/products/$\{remaining}

En el primer ejemplo, una petición a /v1/usuarios/123/perfil se transforma en /api/users/123/perfil antes de llegar al servicio backend. El grupo de captura (?<segment>.*) captura todo después de /v1/usuarios/ y lo utiliza en la URL de destino.

Filtros de prefijo y eliminación de path

Para casos más simples de transformación de URLs, disponemos de los filtros StripPrefix y PrefixPath:

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: api-interna
            uri: lb://SERVICIO-INTERNO
            predicates:
              - Path=/external/api/**
            filters:
              - StripPrefix=2  # Elimina /external/api
              
          - id: servicio-legacy
            uri: lb://SERVICIO-LEGACY
            predicates:
              - Path=/new/**
            filters:
              - StripPrefix=1    # Elimina /new
              - PrefixPath=/legacy/v1  # Añade prefijo

Con StripPrefix=2, una petición a /external/api/usuarios/123 se convierte en /usuarios/123. El valor numérico indica cuántos segmentos de path eliminar desde el inicio.

Filtros de manipulación de headers

Los filtros de headers permiten añadir, modificar o eliminar headers tanto en peticiones como en respuestas:

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: servicio-autenticado
            uri: lb://SERVICIO-SEGURO
            predicates:
              - Path=/secure/**
            filters:
              - AddRequestHeader=X-Gateway-Auth, validated
              - AddRequestHeader=X-Request-ID, #{T(java.util.UUID).randomUUID().toString()}
              - RemoveResponseHeader=X-Internal-Token
              - SetResponseHeader=Cache-Control, no-cache

El filtro utiliza Spring Expression Language (SpEL) para generar valores dinámicos, como el UUID único para cada petición en el header X-Request-ID.

Filtros de parámetros de consulta

Es posible manipular los query parameters de las URLs utilizando filtros específicos:

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: servicio-con-parametros
            uri: lb://SERVICIO-BACKEND
            predicates:
              - Path=/api/search/**
            filters:
              - AddRequestParameter=source, gateway
              - RemoveRequestParameter=debug
              - RewritePath=/api/search, /search

Estos filtros añaden parámetros automáticamente (source=gateway), eliminan otros que no queremos pasar al backend (debug) y reescriben la ruta simultáneamente.

Combinación de múltiples filtros

Los filtros se pueden combinar para crear transformaciones complejas. Se ejecutan en el orden especificado en la configuración:

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: transformacion-completa
            uri: lb://NUEVO-SERVICIO
            predicates:
              - Path=/old-api/v1/**
            filters:
              - StripPrefix=2                    # /old-api/v1/users -> /users
              - PrefixPath=/api/v2              # /users -> /api/v2/users
              - AddRequestHeader=X-Version, v2  # Añadir header de versión
              - AddRequestHeader=X-Migrated, true
              - RemoveRequestParameter=legacy   # Limpiar parámetros legacy

Esta configuración migra peticiones de una API legacy hacia una nueva versión, transformando completamente la URL y añadiendo metadata sobre la migración.

Filtros condicionales con SetPath

El filtro SetPath permite definir rutas completamente nuevas basándose en variables capturadas por predicados:

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: redirection-dinamica
            uri: lb://SERVICIO-FLEXIBLE
            predicates:
              - Path=/redirect/{service}/{version}/**
            filters:
              - SetPath=/{service}/api/{version}/{remaining}
              - AddRequestHeader=X-Original-Path, /redirect/{service}/{version}/{remaining}

Las variables {service}, {version} y {remaining} capturadas por el predicado Path se reutilizan en el filtro SetPath para construir la nueva ruta dinámicamente.

Configuración programática de filtros

Para casos avanzados, es posible definir filtros programáticamente:

@Configuration
public class GatewayFilterConfig {
    
    @Bean
    public RouteLocator filtrosPersonalizados(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("usuarios-transformados", r -> r
                .path("/legacy/users/**")
                .filters(f -> f
                    .rewritePath("/legacy/users/(?<segment>.*)", "/api/v2/usuarios/${segment}")
                    .addRequestHeader("X-Transformation", "legacy-to-v2")
                    .addRequestHeader("X-Timestamp", 
                        String.valueOf(System.currentTimeMillis()))
                    .removeResponseHeader("X-Internal-Version")
                )
                .uri("lb://USUARIOS-SERVICE")
            )
            .build();
    }
}

Debugging y monitorización de filtros

Para depurar el comportamiento de los filtros, podemos activar logging detallado:

logging:
  level:
    org.springframework.cloud.gateway.mvc.filter: DEBUG
    org.springframework.cloud.gateway.mvc.handler: DEBUG

También es útil añadir filtros de logging que nos muestren las transformaciones aplicadas:

spring:
  cloud:
    gateway:
      mvc:
        routes:
          - id: servicio-debug
            uri: lb://MI-SERVICIO
            predicates:
              - Path=/debug/**
            filters:
              - RewritePath=/debug/(?<path>.*), /api/${path}
              - AddRequestHeader=X-Debug-Original, /debug/${path}
              - AddRequestHeader=X-Debug-Rewritten, /api/${path}

Filtros de respuesta y manejo de errores

Los filtros también pueden modificar las respuestas que regresan desde los servicios backend:

spring:
  cloud:
    gateway:
      mvc:
        default-filters:
          - AddResponseHeader=X-Response-Time, #{T(System).currentTimeMillis()}
          - RemoveResponseHeader=X-Internal-Service
        routes:
          - id: servicio-con-respuesta-personalizada
            uri: lb://MI-SERVICIO
            predicates:
              - Path=/api/**
            filters:
              - AddResponseHeader=X-Gateway-Version, 1.0
              - SetResponseHeader=Access-Control-Allow-Origin, "*"

Esta configuración enriquece las respuestas con información adicional y configura headers CORS automáticamente para todas las rutas que coincidan con el patrón /api/**.

Los filtros proporcionan una flexibilidad extraordinaria para adaptar el comportamiento del gateway a las necesidades específicas de cada arquitectura de microservicios, permitiendo transformaciones complejas sin requerir cambios en los servicios backend.

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en SpringBoot

Documentación oficial de SpringBoot
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, SpringBoot es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de SpringBoot

Explora más contenido relacionado con SpringBoot y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender la configuración inicial de un proyecto Spring Cloud Gateway usando el stack servlet.
  • Diferenciar entre stack reactivo y stack servlet en Spring Cloud Gateway.
  • Configurar rutas y predicados Path y Method para enrutar peticiones.
  • Aplicar filtros básicos y avanzados para modificar peticiones y respuestas.
  • Integrar el gateway con Eureka para service discovery y balanceo de carga.

Cursos que incluyen esta lección

Esta lección forma parte de los siguientes cursos estructurados con rutas de aprendizaje