Modern microservices use Eureka Server, OpenFeign, and Spring Cloud LoadBalancer for service discovery, inter-service communication, and load balancing. Together, they enable dynamic service registration, seamless communication, and efficient request distribution across multiple service instances.
- Eureka Server provides service registration and discovery capabilities.
- OpenFeign simplifies REST API communication between microservices.
- Spring Cloud LoadBalancer distributes requests across available service instances.
Eureka Server
Eureka Server is a service registry that allows microservices to register themselves and discover other available services dynamically without using hardcoded URLs.
- Maintains a registry of all active microservice instances.
- Enables dynamic service discovery and improves scalability.
OpenFeign
OpenFeign is a declarative REST client that allows microservices to communicate using Java interfaces without writing boilerplate HTTP client code.
- Reduces the amount of REST client implementation code.
- Integrates seamlessly with Eureka for service discovery
Spring Cloud LoadBalancer
Spring Cloud LoadBalancer is a client-side load balancing library that distributes requests among multiple instances of a service.
- Supports automatic load balancing across service instances.
- Uses Round Robin load balancing by default.
Step-by-Step Application Flow
Follow these steps to create an Application.
Developing Service Discovery
To develop a Service Discovery using Eureka, please refer to this article Java Spring Boot Microservices – Developing Service Discovery.
Developing Microservices
In this project, we are going to develop two Microservices
- employee-service
- address-service
Developing Employee-service Step by Step
Step 1: Create a New Spring Boot Project in Spring Initializr
Create a Spring Boot project named employee-service using Spring Initializr.
Add following Dependencies:
- Spring Boot DevTools
- Spring Data JPA
- MySQL Driver
- Spring Web
- OpenFeign
- Eureka Discovery Client

Step 2: Review the Generated pom.xml File.
The generated pom.xml file should contain the Following Dependency.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://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.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg.employeaap</groupId>
<artifactId>employee-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>employee-service</name>
<description>Employee Service</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</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>
<repositories>
<repository>
<id>netflix-candidates</id>
<name>Netflix Candidates</name>
<url>https://artifactory-oss.prod.netflix.net/artifactory/maven-oss-candidates</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Step 3: Create Schema in MySQL
Go to your MySQL Workbench and create a schema named gfgmicroservicesdemo and inside that create a table called employee and put some sample data as shown in the below image. Here we have created 4 columns and put some sample data.

Now we are going to fetch Employee Data from Employee Table in our Spring Boot project. To do it refer to the following steps. Before moving to IntelliJ IDEA let's look at the complete project structure for our Microservices.

Step 4: Make Changes in Your application.properties File
Now make the following changes in your application.properties file.
spring.datasource.url=jdbc:mysql://localhost:3306/gfgmicroservicesdemo
spring.datasource.username=put your username here
spring.datasource.password=put your password here
spring.application.name=employee-service
server.port=8080
# Set Your Context Path Here
server.servlet.context-path=/employee-service
Step 5: Create Your Entity/Model Class
Go to the src > main > java > entity and create a class Employee and put the below code. This is our model class.
package com.gfg.employeaap.entity;
import jakarta.persistence.*;
@Entity
@Table(name = "employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "email")
private String email;
@Column(name = "age")
private String age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
Step 6: Create Your Repository Interface
Go to the src > main > java > repository and create an interface EmployeeRepo and put the below code. This is our repository where we write code for all the database-related stuff.
package com.gfg.employeaap.repository;
import com.gfg.employeaap.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
@Repository
public interface EmployeeRepo extends JpaRepository<Employee, Integer> {
}
Note: Please refer to this article to know more about JpaRepository.
Step 7: Create an EmployeeResponse and AddressResponse Class
Go to the employee-service > src > main > java > response and create a class AddressResponse and put the below code.
package com.gfg.employeaap.response;
public class AddressResponse {
private int id;
private String city;
private String state;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
Go to the src > main > java > response and create a class EmployeeResponse and put the below code.
package com.gfg.employeaap.response;
public class EmployeeResponse {
private int id;
private String name;
private String email;
private String age;
// Add AddressResponse Here
private AddressResponse addressResponse;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public AddressResponse getAddressResponse() {
return addressResponse;
}
public void setAddressResponse(AddressResponse addressResponse) {
this.addressResponse = addressResponse;
}
}
Step 8: Create an AddressClient Interface
Go to the employee-service > src > main > java > feignclient and create an interface AddressClient and put the below code.
package com.gfg.employeaap.feignclient;
import com.gfg.employeaap.response.AddressResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name = "address-service", url = "http://localhost:8081", path = "/address-service")
public interface AddressClient {
@GetMapping("/address/{id}")
public ResponseEntity<AddressResponse> getAddressByEmployeeId(@PathVariable("id") int id);
}
Step 9: Modify EmployeeServiceApplication Class
Go to the employee-service > src > main > java > EmployeeServiceApplication and annotate it with @EnableFeignClients annotation. Below is the complete code for EmployeeServiceApplication Class.
package com.gfg.employeaap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class EmployeeServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EmployeeServiceApplication.class, args);
}
}
Step 10: Create Your Service Class
Now go to the employee-service > src > main > java > service > EmployeeService and modify the EmployeeService class as below.
package com.gfg.employeaap.service;
import com.gfg.employeaap.entity.Employee;
import com.gfg.employeaap.feignclient.AddressClient;
import com.gfg.employeaap.repository.EmployeeRepo;
import com.gfg.employeaap.response.AddressResponse;
import com.gfg.employeaap.response.EmployeeResponse;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class EmployeeService {
@Autowired
private EmployeeRepo employeeRepo;
@Autowired
private ModelMapper mapper;
// Spring will create the implementation
// for this class
// and will inject the bean here (proxy)
@Autowired
private AddressClient addressClient;
public EmployeeResponse getEmployeeById(int id) {
Optional<Employee> employee = employeeRepo.findById(id);
EmployeeResponse employeeResponse = mapper.map(employee, EmployeeResponse.class);
// Using FeignClient
ResponseEntity<AddressResponse> addressResponse = addressClient.getAddressByEmployeeId(id);
employeeResponse.setAddressResponse(addressResponse.getBody());
return employeeResponse;
}
}
Step 11: Create an Employee Controller
Go to the src > main > java > controller and create a class EmployeeController and put the below code. Here we are going to create an endpoint "/employees/{id}" to find an employee using id.
package com.gfg.employeaap.controller;
import com.gfg.employeaap.response.EmployeeResponse;
import com.gfg.employeaap.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping("/employees/{id}")
private ResponseEntity<EmployeeResponse> getEmployeeDetails(@PathVariable("id") int id) {
EmployeeResponse employee = employeeService.getEmployeeById(id);
return ResponseEntity.status(HttpStatus.OK).body(employee);
}
}
Step 12: Create a Configuration Class
Go to the src > main > java > configuration and create a class EmployeeConfig and put the below code.
package com.gfg.employeaap.configuration;
import com.gfg.employeaap.service.EmployeeService;
import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class EmployeeConfig {
@Bean
public ModelMapper modelMapperBean() {
return new ModelMapper();
}
}
Note: You may refer to these two articles
Developing address-service Step by Step
Step 1: Create a New Spring Boot Project in Spring Initializr
Create a Spring Boot project named employee-service using Spring Initializr.
 Add following dependencies:
- Spring Boot DevTools
- Spring Data JPA
- MySQL Driver
- Spring Web
- Eureka Discovery Client

Generate the project and run it in IntelliJ IDEA by referring to the above article.
Step 2: Review the Generated pom.xml File.
The generated pom.xml file should contain the Following Dependency.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://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.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg.addressapp</groupId>
<artifactId>address-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>address-service</name>
<description>Address Service</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</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>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>netflix-candidates</id>
<name>Netflix Candidates</name>
<url>https://artifactory-oss.prod.netflix.net/artifactory/maven-oss-candidates</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
Step 3: Create Schema in MySQL
Go to your MySQL Workbench and create a schema named gfgmicroservicesdemo and inside that create a table called address and put some sample data as shown in the below image.Â
Note: In the Address table, employee_id is a foreign key so create it accordingly. We are going to perform a SQL join operation in our native SQL query. So create tables carefully.

Before moving to IntelliJ IDEA let's have a look at the complete project structure for our Microservices.

Step 3: Make Changes in Your application.properties File
Now make the following changes in your application.properties file.
spring.datasource.url=jdbc:mysql://localhost:3306/gfgmicroservicesdemo
spring.datasource.username=put your username here
spring.datasource.password=put your password here
spring.application.name=address-service
server.port=8081
server.servlet.context-path=/address-service
Step 4: Create Your Entity/Model Class
Go to the src > main > java > entity and create a class Address and put the below code. This is our model class.
package com.gfg.addressapp.entity;
import jakarta.persistence.*;
@Entity
@Table(name = "address")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "city")
private String city;
@Column(name = "state")
private String state;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
Step 5: Create Your Repository Interface
Go to the src > main > java > repository and create an interface AddressRepo and put the below code. This is our repository where we write code for all the database-related stuff.
package com.gfg.addressapp.repository;
import com.gfg.addressapp.entity.Address;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
@Repository
public interface AddressRepo extends JpaRepository<Address, Integer> {
@Query(
nativeQuery = true,
value
= "SELECT ea.id, ea.city, ea.state FROM gfgmicroservicesdemo.address ea join gfgmicroservicesdemo.employee e on e.id = ea.employee_id where ea.employee_id=:employeeId")
Optional<Address> findAddressByEmployeeId(@Param("employeeId") int employeeId);
}
Step 6: Create an AddressResponse Class
Go to the src > main > java > response and create a class AddressResponse and put the below code.
package com.gfg.addressapp.response;
public class AddressResponse {
private int id;
private String city;
private String state;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
Step 7: Create Your Service Class
Go to the src > main > java > service and create a class AddressService and put the below code. This is our service class where we write our business logic.
package com.gfg.addressapp.service;
import com.gfg.addressapp.entity.Address;
import com.gfg.addressapp.repository.AddressRepo;
import com.gfg.addressapp.response.AddressResponse;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class AddressService {
@Autowired
private AddressRepo addressRepo;
@Autowired
private ModelMapper mapper;
public AddressResponse findAddressByEmployeeId(int employeeId) {
Optional<Address> addressByEmployeeId = addressRepo.findAddressByEmployeeId(employeeId);
AddressResponse addressResponse = mapper.map(addressByEmployeeId, AddressResponse.class);
return addressResponse;
}
}
Step 8: Create an Address Controller
Go to the src > main > java > controller and create a class AddressController and put the below code. Here we are going to create an endpoint "/address/{employeeId}" to find the address using employee_id. Thats why we have created a foreign key in the Address table and we have performed the SQL join operation in the native query to get our desired result.
package com.gfg.addressapp.controller;
import com.gfg.addressapp.response.AddressResponse;
import com.gfg.addressapp.service.AddressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AddressController {
@Autowired
private AddressService addressService;
@GetMapping("/address/{employeeId}")
public ResponseEntity<AddressResponse> getAddressByEmployeeId(@PathVariable("employeeId") int employeeId) {
AddressResponse addressResponse = addressService.findAddressByEmployeeId(employeeId);
return ResponseEntity.status(HttpStatus.OK).body(addressResponse);
}
}
Step 9: Create a Configuration Class
Go to the src > main > java > configuration and create a class AddressConfig and put the below code.
package com.gfg.addressapp.configuration;
import com.gfg.addressapp.service.AddressService;
import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AddressConfig {
@Bean
public ModelMapper modelMapperBean() {
return new ModelMapper();
}
}
Note: You may refer to these two articles
Before running the Microservice below is the complete pom.xml file. Please cross-verify if you have missed some dependencies
Step 10: Run Your Service Discovery, Address, and Employee Microservices
Now run your Service Discovery, Address, and Employee Microservices. If everything goes well then you may see the following screen in your console. Please refer to the below image.

Spring Eureka Dashboard:
.png)
Step 7: Test Your Endpoint in Postman
Now open Postman and hit the following URL
GET: http://localhost:8080/employee-service/employees/2
And you can see the following response as shown in the image.
