I know this question has already been asked, but I have a different scenario in which I have the following structure:
As you can see the front-end (UI) will always call a GraphQL API Gateway microservice that will redirect the request to different microservices depending on the functionality or data required. I simplified the graphic by drawing 3 microservices, but we have more than 30.
When I started working in this project, something that I noticed is that the GraphQL API Gateway microservice is repeating many DTOs that are already defined on the other microservices. As a consequence, this GraphQL API Gateway microservice is full of Java classes that serve as DTOs (with same fields, datatypes and no modifications), so basically, what developers have been doing was to copy and paste a DTO from user microservice and paste them in the GraphQL API Gateway microservice. The same pattern was followed for all the 30 microservices DTOs. Additionally, DTOs across microservices are being copy-pasted based on the needs. You may say that there should not be an issue, but whenever a microservice requires a DTO structure change, we need to change the DTO in all the other microservices.
Some approaches that me and my team evaluated were to:
Either create a common library exclusively for DTOs that could be reused by many projects. The only concern is that this will add some "dependency" and break the "microservices" idea. Additionally, I think this will not fully solve the issue we have since we would need to keep this dependency up to date in each microservice.
Use some sort of utility such JSON schema that will generate required DTOs based on needs.
This is something that I have been discussing with the team, most of the team would like to go for the JSON Schema approach. However, I would like to know if there could be something more efficient from your point of view, I took a look to some approaches like exposing domain objects (https://www.baeldung.com/java-microservices-share-dto), but I do not think this apply for the particular case I am talking in this post.
So, any suggestion or feedback will be highly appreciated. Thanks in advance.
Related
From Design perspective, before development what should be the better way before sharing the contract to consumer, creating RAML first and then generating DTOS or vica versa?
From my understanding there is no difference because both should be done.
RAML is used to document and define API where DTOs play an important role. Defined resources without proper DTOs is uncompleted API. In the same time resource names, query parameters and some other API details are first things to define, so I would go with defining RAML first. Furthermore, when consumer is on a more complicated level than just fetching the data and has some business logic it could be quite expensive to change the use of API if DTOs are not defined. Thus I would advise to agree on this before hand.
It is not possible to see all the details before API implementation starts, but it is better to spend couple of hours more during technical design phase than couple of days or weeks during implementation phase when API requirements change.
In client-server applications with spring-boot and angular. Most resources I find explain how to expose REST endpoint from spring boot and consume it from angular with an http client.
Most of the time, communicating in JSON is preconized, maintaining DTOs (DataTransfertObject) in both angular and spring boot side.
I wonder if people with fullstack experience knows some alternative avoiding maintaining DTOs in both front and backend, maybe sharing models between the two ends of the application?
Swagger would be a good tool to use here.
You can take a code-first approach which will generate a swagger spec from your Java controllers & TOs or a spec-first approach which will generate your Java controllers & TOs from a swagger spec.
Either way, you can then use the swagger spec to generate a set of TypeScript interfaces for the client side.
As Pace said Swagger would be a great feature that you can use. In this case plus having great documentation for the API endpoints you can sync object models between frontend and backend. You have to just use the .json or .yaml file of Swagger to generate the services and object models on the frontend side by using ng-swagger-gen.
Then put the command for generating services and object model in package.json when you wanna build or run your application for instance:
...
"scripts": {
...
"start": "ng-swagger-gen && ng serve",
"build": "ng-swagger-gen && ng build -prod"
...
},
...
So after running one of these commands you will have updated object models and if an object property name or type changed, add/remove object property you will get the error and you have to fix it first then move forward.
Note: Just keep in mind the services and object models will be generated based on the Swagger file so it always should be updated.
PS: I was working on a project that we even every code on the backend side was generated based on the Swagger file ;) so they just change the Swagger file and that's it.
This is a difficult topic, since we are dealing with two different technology stacks. The only way I see is to generate those objects from a common data model.
Sounds good, doesn't work. It is not just about maintaining dto's.
Lets say api changes String to List. It is not enough to update your typescript dto from string to string[]. There is logic behind string manipulation that now needs to handle list of strings. Personally i do not find that troublesome to maintain dto's on both sides. Small tradeoff for flexibility and cleaner code (you will have different methods in different dto's)
I am new to Spring and Hibernate. I am actually facing problems defining the layers of my application which is to create a movie site where one can search movies,theaters,search movies by theater names and theaters by movie name.I summing up my queries as follows :-
What could be the entities in my application, I have created MovieEntity and TheaterEntity so far, how to proceed with the mappings between two.
My project structure should be something like this:
Entities, repositories and services. I am not sure where to fit my service layer, as all the methods I need to implement are defined in entities.
Thanks in advance .
There are many ways to do this, and therefore you will not find one definitive answer to your question. (I didn't downvote you, but I suspect that this is the reason for it.)
I would recommend looking at various open source projects (check github) and see how this is done by convention.
One popular way is to create DAO interfaces as a point of access to your data layer and create implementations of those DAOs that are specific to Hibernate. Your services would contain business logic and can use Spring autowiring to link to these interfaces. Your controllers shouldn't contain business logic and should really just route requests. Keep your validation code separate whenever possible too. Doing so makes it particularly easy to unit test.
I am developing an app using MVC pattern.
Controllers: servlets
Model: I am following DAO/DTO pattern for accessing database
View: simple JSP EL and JSTL
For accessing database I am using DAO pattern. I want to put validation method and a HashMap for error messages inside the DTO classes for validating FORM data, something similar to Putting validation method and hashmap into DTO.
My question is - this a right approach? If not what is an ideal way for doing this?
As a summary: I want to know real world solutions for server side form validation when we are using DAO/DTO pattern. Please help me.
I believe you need to treat separately the architecture you're implementing and the frameworks you're using to implement the architecture.
Java has a rich set of tools for working on the three standard tiers of your application and choices depend on some factors like expected load and server resources, if you have a two or three users application then it is just a matter of taste.
In terms of DAO/DTO then you have also some options, for example you can build your Data access layer with hibernate and then for your service layer API use DTO's. In this situation you probably want to use a tool for mapping between your domain model and your DTO's (for example jDTO Binder).
Another common approach is to use Spring JDBC Template, there you can go a little bit more crazy and use the same Domain objects as part of the Service layer API.
Finally, the truth is, you can do this by the book or you can do it completely different choice is based on your scenario, taste and experience.
I have a JAX-RS service (I use Jersey), and now I have to do the client. I was wondering how you guys use to deal with the model objects.
Do you put you model classes in a different jar in order to share it between the client and the server? Do you always use DTO or do you sometimes (always?) returns jpa entities.
The service I have to use (I haven't created it but I can modify it), often returns entities so I was wondering if it wasn't a bit weird if I externalize those classes.
What do you think? What are you use to do?
It depends on the complexity of the project and on the purpose you use JAX-RS in it:
for very simple projects I wouldn't create one more DTO layer whatsoever
for a project like yours that seems to use JAX-RS just to move data from a java client to a java server I wouldn't create one more layer either. That's because you are in charge at both ends (client and server) and because you reuse the same objects in both places (putting them in a separate jar and maven module is a good idea)
for projects that use JAX-RS to expose an API to external clients it's a good idea to separate the model from the API with DTOs so they are allowed to evolve independently. For example you don't always want to expose all the fields via an API or to break your clients when changing something in the model.
LATER EDIT
for a project that transfers only a subset of their model data fields to the client a DTO layer is useful for efficiency reasons