I'm working on a project with multiple microservices registered with a Eureka Discovery Server. I've set up a Spring Cloud Gateway as an Eureka client and configured the routes accordingly. However, my requests through the Gateway result in 404 errors, while direct requests to the microservices succeed.
API Gateway application.properties:
eureka.client.service-url.defaultZone= http://localhost:8761/eureka/
spring.application.name=api-gateway
server.port=8080
##Product Service Route
spring.cloud.gateway.routes[0].id=product-service
spring.cloud.gateway.routes[0].uri=lb://product-service
spring.cloud.gateway.routes[0].predicates[0]=Path=/api/product
##Order Service Route
spring.cloud.gateway.routes[1].id=order-service
spring.cloud.gateway.routes[1].uri=lb://order-service
spring.cloud.gateway.routes[1].predicates[0]=Path=/api/order
ApiGatewayMain:
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);
}
}
pom.xml:
<artifactId>api-gateway</artifactId>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-cloud.version>2023.0.0</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway-mvc</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-actuator</artifactId>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
Both my microservices (order-service and product-service) have server.port=0 for random port selection and are registered with Eureka:
order-service and product-service application.properties:
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
spring.application.name=order-service # for order-service
# spring.application.name=product-service # for product-service
OrderController:
@RestController
@RequestMapping("/api/order")
@RequiredArgsConstructor
public class OrderController {
private final OrderService orderService;
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public String placeOrder(@RequestBody OrderRequest orderRequest) {
orderService.placeOrder(orderRequest);
return "Order placed successfully";
}
// ... other methods ...
}
ProductController:
@RestController
@RequestMapping("/api/product")
@RequiredArgsConstructor
public class ProductController {
private final ProductService productService;
// ... methods ...
}
Issue:
When making a POST request to http://localhost:8080/api/order via Postman, I receive the following error:
{
"timestamp": "2024-03-08T20:08:59.340+00:00",
"status": 404,
"error": "Not Found",
"path": "/api/order"
}
However, directly calling the order-service using its dynamically assigned port, such as http://localhost:54062/api/order
, works correctly and I receive a Order placed successfully
response.
What am I missing in my Gateway setup that's preventing it from routing requests to the microservices? Any insights or troubleshooting tips would be greatly appreciated.
Please use
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
instead of
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway-mvc</artifactId>
</dependency>