Search code examples
javanetflix-eurekaspring-cloud-gateway

Spring Cloud Gateway with Eureka discovery locator - 404


I'm setting up a microservices based application using Spring Cloud Gateway with Eureka discovery client.

I have configured the Eureka server application, the Gateway application and a regular service.

I have set spring.cloud.gateway.discovery.locator.enabled and spring.cloud.gateway.discovery.locator.lower-case-service-id to true in the Gateway application.yml file.

All three applications start correctly, however when I try to access the microservice through the Gateway I get a 404 error, sending a GET request to localhost:8080/event

I have configured actuator to display the endpoints exposed by the Gateway and there is an entry for the service.

What am I missing?

Eureka Server application.yml

spring:
    application:
        name: registry
server:
    port: 8081

eureka:
    client:
        register-with-eureka: false
        fetch-registry: false
        service-url:
            defaultZone: http://localhost:${server.port}/eureka/
    instance:
        hostname: localhost
        prefer-ip-address: true

Spring Cloud Gateway application.yml

spring:
    application:
        name: api-gateway
    cloud:
        gateway:
            discovery:
                locator:
                    enabled: true
                    lower-case-service-id: true
    main:
        web-application-type: reactive

server:
    port: 8080

eureka:
    client:
        service-url:
            defaultZone: http://localhost:8081/eureka/
        fetch-registry: true
        register-with-eureka: true
    instance:
        hostname: localhost
        prefer-ip-address: true

management:
  endpoint:
    gateway:
      enabled: true
  endpoints:
    web:
      exposure:
        include:
        - "*"

Service application.yml

server:
  port: 8082

spring:
  application:
    name: event

eureka:
    client:
        service-url:
            defaultZone: http://localhost:8081/eureka/
        fetch-registry: true
        register-with-eureka: true
    instance:
        hostname: localhost
        prefer-ip-address: true

I have included the required annotations on both Eureka server application and Gateway and Event service application classes. I get the following response when querying http://localhost:8080/actuator/gateway/routes:

[{"predicate":"Paths: [/api-gateway/**], match trailing slash: true","metadata":{"jmx.port":"55939","management.port":"8080"},"route_id":"ReactiveCompositeDiscoveryClient_API-GATEWAY","filters":["[[RewritePath /api-gateway/?(?<remaining>.*) = '/${remaining}'], order = 1]"],"uri":"lb://API-GATEWAY","order":0},{"predicate":"Paths: [/event/**], match trailing slash: true","metadata":{"jmx.port":"55880","management.port":"8082"},"route_id":"ReactiveCompositeDiscoveryClient_EVENT","filters":["[[RewritePath /event/?(?<remaining>.*) = '/${remaining}'], order = 1]"],"uri":"lb://EVENT","order":0}]

EventController

package example.event.endpoint.controller;

import static org.springframework.http.HttpStatus.OK;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import example.event.endpoint.service.EventService;
import example.core.model.Event;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@RestController
@RequestMapping("/v1/event")
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class EventController {
    private final EventService eventService;

    @GetMapping
    public ResponseEntity<Iterable<Event>> listAll(Pageable pageable) {
        log.info("Retrieving all events");
        return new ResponseEntity<>(eventService.list(pageable), OK);
    }
}


Solution

  • If localhost:8082/v1/event returns your desired output I would expect the same from gateway localhost:8080/event/v1/event to route based on your configuration.

    The first /event is your service name used by the spring cloud gateway to determine which service it needs to route. By default, the service name gets trimmed, and the /v1/event path along with any other request part is routed to your event service.