3

I have 4 services as given below -

  1. Notes-service -- takes NotesRequest and produces NotesResponse
  2. Reminder-service -- takes ReminderRequest and produces ReminderResponse
  3. Todo-service -- takes TodoRequest and produces TodoResponse
  4. Personal-assistant service -- takes AssistantRequest and AssistantResponse

Personal-assistant service calls the 3 services internally, the Notes-service, Reminder-service and the Todo-service. Notes-service will contain these two request and response pojos inside it --

  1. NotesRequest.java
  2. NotesResponse.java

But to call this with the help of a Rest client, Personal-assistant will also require these pojos. A possible way could be to create a common module with the name of common-service and put the sharable request response objects for each service in common-service. Each of the service modules will have a dependency to common-service.

Is there any good approach to put the code clean and modular and make the deployments independent.

Yogesh Sharma
  • 280
  • 1
  • 13

1 Answers1

1

I would consider 2 possibilities:

1.- Use a framework like swagger (or similiar) to expose the API specification(through OpenAPI for instance). This can be used with code generation tools to generate the client. And make the client generation part of the build process in the projects that need to use a client of that service. Do not version control generated code, that's a bad practice.

2.- Create in each service project a contract module, in which you will have just the contract (requests, responses, and api interface, like JAX-RS interface, or Spring interfaces). This module can be used as a dependency in the projects that need a client for that service.

Which one to use depends on the technologies you use and the clients requirements and standards used.

Update with examples

For instance, with the option 2 you will have the following project structure for the notes project:

-notes-parent
    -notes-contract
    -notes-service

Each one with its pom.xml.:

  • parent would be just a container root module
  • contract contains the requests, responses, and services intrfaces. This would be used as a dependency for the project that want to query the notes-service
  • service the deployable service itself. This will use the contract as a dependency too.

And do this with all the services. Every xxx-service submodule will have as dependencies all the yyy-contract modules of the other services it wants to query.

gmanjon
  • 1,483
  • 1
  • 12
  • 16
  • 1
    Okay, I was able to understand the first approach a little, so if we are using Spring boot REST style and json as a communication medium, then using swagger, we can generate the json (or may be json schema if we could) request and response templates. Now we can include this json schema in the client modules and generate the java pojos using a maven plugin and this way clients would be able to call the service and they will be in sync with the changes to the API too. please correct me if i misunderstood. Thanks for the answer... – Yogesh Sharma Jan 20 '22 at 17:39
  • 1
    Yes, you understood it correctly. Whenever the contract changes you just have to update the json in the clients. If you use Spring+swagger you can see the json specification path in the swagger-ui home, referenced at the top, because that spec is exactly what swagger-ui uses to generate the web app. – gmanjon Jan 20 '22 at 17:53
  • @gmanjon Does it mean the two services (the caller and callee) have the same duplicate JSON Swagger files? If I update the JSON file in note-service, I will also update the file in personal-assisitance-service? – emeraldhieu Mar 26 '23 at 17:47
  • Yes and no. The json in the callee is not something you modify, is autogenerated from your interfaces/request/responses at runtime. But yes, that same file should reside as well in the caller to be able to generate the client. Or you can just create a separate library that contains the generated code, as a separate artifact. I expressed two ideas (1 expose an specification, 2 expose a client library), but then there are many ways to implement them. – gmanjon Mar 28 '23 at 14:21