Service Discovery with Spring Cloud Eureka

In a microservices architecture, services often scale dynamically. IPs and ports change, and hardcoding service URLs becomes unreliable. This is where Service Discovery comes in.

Spring Boot Eureka Service Discovery, part of the Spring Cloud Netflix stack, enables automatic service registration and lookup, making it seamless for services to find each other.

In this post, weโ€™ll explore:

  • What is Eureka
  • How to create a Eureka Server
  • How to register microservices as Eureka clients
  • How to test service discovery

All code examples use com.kscodes.springboot.microservice as the base package.

Spring Boot Eureka Service Discovery,

๐Ÿงฑ What is Eureka?

Eureka is a REST-based service registry by Netflix. It has two main roles:

  • Eureka Server: Hosts the service registry
  • Eureka Client: Registers with the server and discovers other services

๐Ÿ›  Project Setup Overview

Weโ€™ll create three components:

  1. Eureka Server โ€“ Runs on port 8761
  2. Customer Service โ€“ Registers as a Eureka client (port 8081)
  3. Order Service โ€“ Discovers and calls Customer Service via Eureka (port 8082)

๐Ÿ“ฆ Create the Eureka Server

๐Ÿ“ Package: com.kscodes.springboot.microservice.discoveryserver

pom.xml




  
    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-server
  
  
    org.springframework.boot
    spring-boot-starter-web
  



  
    
      org.springframework.cloud
      spring-cloud-dependencies
      2022.0.4
      pom
      import
    
  


EurekaServerApplication.java


package com.kscodes.springboot.microservice.discoveryserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

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

application.yml


server:
  port: 8761

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
spring:
  application:
    name: discovery-server

๐Ÿ“ฆ Create Customer Service (Client)

๐Ÿ“ Package: com.kscodes.springboot.microservice.customer

pom.xml additions:



  org.springframework.cloud
  spring-cloud-starter-netflix-eureka-client


CustomerServiceApplication.java


package com.kscodes.springboot.microservice.customer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

application.yml


server:
  port: 8081
spring:
  application:
    name: customer-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

CustomerController.java


package com.kscodes.springboot.microservice.customer;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/customers")
public class CustomerController {

    @GetMapping("/{id}")
    public String getCustomer(@PathVariable Long id) {
        return "Customer-" + id;
    }
}

๐Ÿ“ฆ Create Order Service (Client)

๐Ÿ“ Package: com.kscodes.springboot.microservice.order

This service discovers customer-service from Eureka and makes REST calls.

OrderServiceApplication.java


package com.kscodes.springboot.microservice.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

application.yml


server:
  port: 8082
spring:
  application:
    name: order-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

OrderController.java


package com.kscodes.springboot.microservice.order;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/api/orders")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/{id}")
    public String getOrder(@PathVariable Long id) {
        String customer = restTemplate.getForObject("http://CUSTOMER-SERVICE/api/customers/1", String.class);
        return "Order ID: " + id + ", Customer: " + customer;
    }
}

Note: CUSTOMER-SERVICE is resolved dynamically by Eureka from the service registry.

๐Ÿงช Test the Setup

  1. Start EurekaServerApplication (port 8761)
  2. Start CustomerServiceApplication (port 8081)
  3. Start OrderServiceApplication (port 8082)
  4. Open http://localhost:8761 and see the registered services
  5. Call http://localhost:8082/api/orders/99
    โ†’ You should see customer info from service discovery!

๐Ÿ“š Summary

In this post, you learned how to use Spring Boot Eureka Service Discovery to register and discover microservices dynamically. You built:

  • A Eureka server
  • Two Spring Boot clients
  • A working REST interaction using logical service names

Using Spring Boot Eureka Service Discovery, your architecture becomes more resilient and adaptable in distributed environments.