Building microservices with a gateway and Eureka, like your Zayka project

Microservices sound simple: split one big app into small services. In practice, the first week usually goes on making the services find each other and start up at all. Here is the setup I used in my own project, ZaykaHub, a food ordering platform with user, restaurant, item, order and payment services, and the problems I had to fix along the way.

The basic shape

  • Discovery server (Eureka), port 8761. A phone book: every service registers here, and others look it up by name.
  • API gateway, port 8080. The single front door. Clients call only the gateway, which forwards each request to the right service.
  • Business services: user-service, item-service, order-service, payment-service. Each has its own database and runs on its own port.

The client never needs to know where order-service is running. It calls /api/orders on the gateway and the gateway works out the rest.

Step 1: The discovery server

Add spring-cloud-starter-netflix-eureka-server, then:

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryApplication {
    public static void main(String[] args) {
        SpringApplication.run(DiscoveryApplication.class, args);
    }
}
# application.yml
server:
  port: 8761
eureka:
  client:
    register-with-eureka: false   # the server doesn't register with itself
    fetch-registry: false

Open http://localhost:8761. You should see the Eureka dashboard with no services listed yet.

Step 2: Register each service

Add spring-cloud-starter-netflix-eureka-client to every business service and give each one a unique name and port:

spring:
  application:
    name: order-service
server:
  port: 8083
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

Restart the service and refresh the dashboard. ORDER-SERVICE should appear.

Step 3: The gateway

Add Spring Cloud Gateway plus the Eureka client, and define routes in Java:

@Bean
RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("users",  r -> r.path("/api/users/**").uri("lb://user-service"))
        .route("orders", r -> r.path("/api/orders/**").uri("lb://order-service"))
        .route("pay",    r -> r.path("/api/payments/**").uri("lb://payment-service"))
        .build();
}

lb://order-service means "ask Eureka where order-service is, and load-balance if there are several copies". No hard-coded hosts or ports.

The problems nobody warns you about

1. "Port 8080 was already in use"

Two services, or an old process you forgot about, are trying to use the same port. Give every service its own fixed port in application.yml, and keep a simple table of which service uses which. To find what is holding a port: netstat -ano | findstr :8080 on Windows, or lsof -i :8080 on Mac/Linux.

2. Spring Cloud and Spring Boot versions that don't match

Each Spring Cloud release train supports specific Spring Boot versions. Mixing them gives confusing startup errors. Import the Spring Cloud BOM that matches your Boot version once, in the parent pom.xml, and never set versions on individual Spring Cloud starters:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>  <!-- check the compatibility table -->
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

3. Logging and Jackson conflicts

One old library can pull in SLF4J 1.7 or an older Jackson, and then a service fails at startup or logs nothing. Run mvn dependency:tree, find the old version, and exclude it. Let Spring Boot manage these versions.

4. "Unsupported class file major version"

The code was compiled with a newer Java than the one running it. Spring Boot 3 needs Java 17 or later. Check JAVA_HOME, your IDE's project SDK and Maven's Java version. They must all match.

5. A service doesn't appear in Eureka

Usually the Eureka client dependency is missing, the defaultZone URL is wrong, or the service started before the discovery server. Start the discovery server first, then the services, then the gateway.

Start-up order checklist

  1. Discovery server (8761): dashboard opens
  2. Business services: each one shows up on the dashboard
  3. Gateway (8080): calls to /api/... reach the right service
Need a microservices backend built or fixed?
I design and build Spring Boot microservices (gateway, service discovery, Kafka, PostgreSQL/Oracle, Docker) and fix the ones that won't start or keep failing. I have 15 years in banking and insurance backends.
See how I work → or email sheikhhameed007@gmail.com

Comments