1. An overview of the

In recent years, microservices have become more and more popular. The basic characteristics of microservices are modular, independent, and easy to expand. ** They need to work together and exchange data. ** To achieve this, we created a shared data transfer object named DTO. In this article, we’ll show you how to share Dtos between microservices.

2. Publish domain objects as Dtos

Models representing application domains using microservice management. The domain model has different concerns than the DTO, and we separate them from the data model in the DAO layer. The main reason for this is that we don’t want to expose the complexity of our domain to our clients through our services.

Instead, we expose Dtos to serve clients through REST apis. As dtos are passed between these services, we convert them into domain objects.

The above service-oriented architecture schematically shows the components and flow of dTO-domain objects.

3. Share dtos between microservices

Take the process of a customer ordering a product. This process is based on the Customer-Order model, looking at the process from a service architecture perspective. Suppose the customer service sends the request data to the order service:

"order": {
    "customerId": 1."itemId": "A152"
}
Copy the code

Customer and Order services use contracts to communicate. Contracts (or service requests) are displayed in JSON format. As a Java model, the OrderDTO class represents the contract between the customer service and the order service:

public class OrderDTO {
    private int customerId;
    private String itemId;

    // constructor, getters, setters
}
Copy the code

3.1. Share dtos using client modules

Microservices require some information from other services to process any request. Suppose there is a third microservice that receives a payment request for an order. Unlike the order service, this service requires different customer information:

public class CustomerDTO {
    private String firstName;
    private String lastName;
    private String cardNumber;

    // constructor, getters, setters
}
Copy the code

If we also added a delivery service, the customer information would have:

public class CustomerDTO {
    private String firstName;
    private String lastName;
    private String homeAddress;
    private String contactNumber;

    // constructor, getters, setters
}
Copy the code

Therefore, putting the CustomerDTO class in the shared module does not work as expected. To solve this problem, we took a different approach.

In each microservice module, create a client module (dependency package) and create a server module next to it:

order-service
|__ order-client
|__ order-server
Copy the code

The Order-Client module contains a DTO shared with the customer service. Therefore, the ORder-Client module has the following structure:

order-service└ ─ ─ the order-client
     OrderClient.java
     OrderClientImpl.java
     OrderDTO.java
Copy the code

OrderClient is an interface that defines the order method for processing order requests:

public interface OrderClient {
    OrderResponse order(OrderDTO orderDTO);
}
Copy the code

To implement the ORDER method, we use the RestTemplate object to send a POST request to the Order service:

String serviceUrl = "http://localhost:8002/order-service";
OrderResponse orderResponse = restTemplate.postForObject(serviceUrl + "/create", 
  request, OrderResponse.class);
Copy the code

In addition, the Order-Client module is already available. It now becomes a dependent library for the Customer-service module:

[INFO] -- maven-dependency plugin:3.1.2:list (default-cli) @customer-service -- [INFO] The following files have been Resolved: [INFO] com. Baeldung. Orderservice: order - client: jar: 1.0 the SNAPSHOT: the compileCopy the code

Of course, if the order-server module does not expose /create service endpoints to the order-client, that would not work either!

@PostMapping("/create")
public OrderResponse createOrder(@RequestBody OrderDTO request)
Copy the code

Because of this Service endpoint, the Customer Service can send an order request through its Order client. By using client modules, microservices communicate with each other in a more independent manner. Properties in the DTO are updated in the client module. Therefore, contract violations are limited to services that use the same client module.

4. Conclusion

This article explained a way to share DTOS between microservices. At best, we do this by signing special contracts as part of the microservice client module (library). In this way, we separate the service client from the part of the server that contains the API resources. The benefits of this are:

  • There is no redundancy between services
  • Contract violations are limited to services that use the same client