Implementation of the Microservices Communication via HTTP and JSON
We will develop the two simple microservices. Then two services will communicate through the HTTP and JSON of the application.
Create the User-Service
Step 1: Create a new Spring Boot project using Spring Initializr, and add the below dependencies:
- Spring Web
- Apache ActiveMQ
- Spring DevTools
- Lombok
After this project creation done, the project structure will be like below:
Step 2: Open application.properties file and add the application name, server port configuration of the project.
spring.application.name=user-service
server.port=8082
Step 3: Create the User class
Go to src > org.example.userservice > model > User and put the below code.
package org.example.userservice.model;
import lombok.Data;
@Data
public class User {
private String userId;
private String name;
private String email;
public User() {
}
public User(String userId, String name, String email) {
this.userId = userId;
this.name = name;
this.email = email;
}
}
Step 4: Create the UserService class.
Go to src > org.example.userservice > service > UserService and put the below code.
package org.example.userservice.service;
import org.example.userservice.model.User;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public User getUserById(String userId) {
return new User(userId, "John Doe", "john@example.com");
}
public User getUserByName(String name) {
// Mock data, in real scenarios, fetch from database
if ("John Doe".equals(name)) {
return new User("U12345", name, "john@example.com");
}
return null;
}
}
Step 5: Create the UserController Class
Go to src > org.example.userservice > controller > UserController and put the below code.
package org.example.userservice.controller;
import org.example.userservice.model.User;
import org.example.userservice.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{userId}")
public ResponseEntity<User> getUser(@PathVariable String userId) {
User user = userService.getUserById(userId);
return ResponseEntity.ok(user);
}
@GetMapping("/byname")
public ResponseEntity<User> getUserByName(@RequestParam String name) {
User user = userService.getUserByName(name);
return ResponseEntity.ok(user);
}
}
Step 6: Open the main class. (No changes are required)
package org.example.userservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://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.2.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>user-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>user-service</name>
<description>user-service</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<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>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<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>
</project>
Step 7: Run the application
Now we will run the project and it will run at port 8082.
Create the Order-service
Step 1: Create a new Spring Boot project using Spring Initializr, and add below dependencies:
- Spring Web
- Apache ActiveMQ
- Spring DevTools
- Lombok
After the Project creation done, the folder structure will be like below image.
Step 2: Open application.properties file and add the application name, server port configuration.
spring.application.name=order-service
server.port=8081
Step 3: Create the Order class
Go to src > org.example.orderservice > model > Order and put the below code.
package org.example.orderservice.model;
import lombok.Data;
@Data
public class Order {
private String orderId;
private String userId;
private double amount;
public Order() {
}
public Order(String orderId, String userId, double amount) {
this.orderId = orderId;
this.userId = userId;
this.amount = amount;
}
}
Step 4: Create the OrderDetails class
Go to src > org.example.orderservice > model > OrderDetails and put the below code.
package org.example.orderservice.model;
import lombok.Data;
@Data
public class OrderDetails {
private Order order;
private User user;
public OrderDetails() {
}
public OrderDetails(Order order, User user) {
this.order = order;
this.user = user;
}
}
Step 5: Create the User class
Go to src > org.example.orderservice > model > User and put the below code.
package org.example.orderservice.model;
import lombok.Data;
@Data
public class User {
private String userId;
private String name;
private String email;
public User() {
}
public User(String userId, String name, String email) {
this.userId = userId;
this.name = name;
this.email = email;
}
}
Step 6: Create the RestTemplateConfig class
Go to src > org.example.orderservice > config > RestTemplateConfig and put the below code.
package org.example.orderservice.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Step 7: Create the OrderService class
Go to src > org.example.orderservice > service > OrderService and put the below code.
package org.example.orderservice.service;
import org.example.orderservice.model.Order;
import org.example.orderservice.model.OrderDetails;
import org.example.orderservice.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.ResourceAccessException;
@Service
public class OrderService {
@Autowired
private RestTemplate restTemplate;
public OrderDetails getOrderDetails(String orderId) {
// Mock data
Order order = new Order(orderId, "U12345", 250.75);
User user = restTemplate.getForObject("http://localhost:8082/users/" + order.getUserId(), User.class);
return new OrderDetails(order, user);
}
public OrderDetails getOrderDetailsByUserName(String name) {
try {
User user = restTemplate.getForObject("http://localhost:8082/users/byname?name=" + name, User.class);
if (user != null) {
// Mock data
Order order = new Order("12345", user.getUserId(), 250.75);
return new OrderDetails(order, user);
} else {
return null;
}
} catch (ResourceAccessException e) {
System.err.println("Error connecting to UserService: " + e.getMessage());
return null;
}
}
}
Step 8: Create the OrderController class
Go to src > org.example.orderservice > controller > OrderController and put the below code.
package org.example.orderservice.controller;
import org.example.orderservice.model.OrderDetails;
import org.example.orderservice.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/{orderId}")
public ResponseEntity<OrderDetails> getOrder(@PathVariable String orderId) {
OrderDetails orderDetails = orderService.getOrderDetails(orderId);
return ResponseEntity.ok(orderDetails);
}
@GetMapping("/byusername")
public ResponseEntity<OrderDetails> getOrderByUserName(@RequestParam String name) {
OrderDetails orderDetails = orderService.getOrderDetailsByUserName(name);
return ResponseEntity.ok(orderDetails);
}
}
Step 9: Open the main class and write the below code. (No changes are required)
package org.example.orderservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://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.2.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>order-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>order-service</name>
<description>order-service</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<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>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<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>
</project>
Step 10: Run the application
Once we run the application, the application will start at port 8081.
Order by username Endpoint Testing:
GET http://localhost:8081/order/byusername?name=John Doe
Output:
By following these steps, we can set up the two microservices (UserService, OrderService ) that communicate via the HTTP using JSON. This example project demonstrates how microservices can interact seamlessly and it allow us to build scalable and maintainable applications.
Microservices Communication via HTTP and JSON
A microservice architecture is used to build an application as a collection of loosely coupled, independently deployable services. These applications can interact with each other to achieve synergistic functionality. The most common way for microservices to communicate is to use JSON as the data exchange format using HTTP which is a widely supported protocol. It can provide a reliable way for any service to send a request and receive a response. JSON is a small data exchange format and is easy to parse and manipulate.
Microservices communicate via HTTP by calling each other’s APIs. Each microservice can expose a RESTful API and other microservices can interact with these APIs to perform various tasks. JSON can be used as a data exchange format because it is lightweight and easy to work with.
Overview of how microservices communicate
- Service discovery: Microservices can register with a user discovery tool like Eureka so they can find each other.
- API Gateway: This can act as an entry point for clients, sending requests to the appropriate microservices.
- HTTP requests: Microservices can send HTTP requests to communicate with each other via JSON to exchange data.