Redundant classes in Microservice architecture - microservices

I just moved to a new project, and it is a legacy code, having 15 microservices.
Problem is each service has 3-4 common classes, e.g. User.java, Supplier.java, Settings.java. Whenever we need do any change in any of those classes in any of the microservices then we have to do that change in rest of other 14 apis as well, which is so tiring.
Is there any workaround for this problem?

Yes, we use RestTemplate to make api calls to our apis and have made each service expose a set of jars that defines the model, basic api calls on that model handling retries and stuff and expose each of them aligned with the api version.
Other services when import these and use them. Say they want user data they use make a function call to the method getUser and which in turn makes the api call fetches the data and respond back.
We try not to make breaking changes in apis and incrementally release new api version and new jar to be used by other system.
Note this is completely optional and its up to the service if they want to make use of the jars or if they want to make an api call directly.

Related

Spring Beans Dependency Inyection with different configurations

I have the following doubt, probably a very basic one, that I have already managed to work out but I would like to listen if there is a different approach or actually if I am getting something wrong.
Background
I have an implementation with Springboot with a classic layered approach using Spring StereoTypes and wiring all up using Field DI (yes... I am aware it is not the best approach)
Service -> Repository -> (Something else)
In my case (something else) is a third party Rest API which I am calling using a RestTemplate with a specific configuration.The current solution has many services and repositories to deal with each of the Third Party domain entities. All of them using the same RestTemplate bean. The bean is inyected at the repository level.
Problem
So now I have been told from the Third Party System that depending on which business scenario my local services are executing, repositories need to use one of two different users, therefore, I assume that a different restTemplate config needs to be added. At first glance it drives me to move even higher the decision of which restTemplate to use. At Service level, not at the repo level. So I would need to have, lets say, a service A under a specific context whose dependencies (the repository) will need to have a specific template, and the same service A given another context, with a different dependency config.
Approach
The approach that I took is to have a configuration class where I generate different versions of the same service with different dependencies, in particular, their repositories using a specific template. Github Example
This approach seems like odd to me because up till now I have never had to do something like this ...and leaves me with the doubt if something different can be done to achive the same.
Another approach would be to inject both RestTemplates in the base repository and with an extra parameter to decide which to use in each method that it is being use at service level and repo level. Which I dislike.

Two approaches to implementing REST API on Spring

I do REST API on Spring. Took a course in Spring Data Hibernate and found that it made the REST API the most time-consuming way.
When I added a new entity to the domain, I went through the following chain of objects:
Entity - domain object
DTO - for transmitting/receiving an object to/from a client
Mapper - to convert between Entity and DTO
Repository - for interacting with the database
RestController - for processing API requests
Service - service class for the object
The approximate chain of my actions was as follows:
RestController processes requests - receives DTO from the client (in case of creation of a new object)
Mapper in controller converts DTO to Entity
Service is called
Service accesses the Repository
Repository returns the result of execution (created by Entity)
Service returns Entity is created in RestController
RestController returns to the client an object of type ResponseEntity, where I put the body and response code.
As you can see a large chain of actions and a large number of objects.
But then I found out that if you use Spring Data REST, all this doesn't need all the API supplied by Spring from the box. In general, you only need to create an Entity and Repository.
It turns out that for typical CRUD-type operations, I wrote a lot of controllers and their methods in vain.
Questions:
When should I use RestConroller, and when is Spring Data REST?
Is it possible to combine two approaches for one Entity? It turns out that I was wasting my time writing for simple operations like creating, getting, saving, deleting controllers, it can be moved to Spring Data REST.
Will I be able to implement some of the actions that I did in Spring Data Rest in RestConroller? Such as:
Return an entity property value as id instead of object? I mean I have properties for entities that are entities themselves, for these fields I sometimes need to return their ID instead of the whole entity.
Is there any way to control error handling? In RestController I have implemented the ResponseEntityExceptionHandler extension class and all errors wherever they occur in my RestController are handled in the same way in one place and I always know that all errors will return approximately the same response structure.
Data validation will have to be hinged on the fact that it used to be validated on DTOs received from the client. Are there any nuances waiting for me in this regard?
I'm a little stumped on how to move forward. Give me your recommendations and thoughts on this. Push forward on what to use and how.
What Spring Data REST can do for you is scaffolding of the plain repository to rest service. It is much faster, and in theory it should be flexible, but in practice it is hard to achieve something more than REST access to your repositories.
In production I've used Spring Data REST as a wrapper of the database - in a service/microservice architecture model you just wrap-up sometimes the core DB into such layer in order to achieve DB-agnostic Application. Then the services will apply the business logic on top of this wrapper and will provide API for the front-end.
On the other hand Spring Data Rest(SDR) is not suitable if you plan to use only these generated endpoints, because you need to customize the logic for fetching data and data manipulation into Repoitories/Services. You can combine both and use SDR for the "simple" entities, where you need only the basic CRUD over them, and for the complex entities to go with the standard approach, where you decouple the entity from the endopint and apply your custom business logic into the services. The downside of mixing up both strategies is that your app will be not consistent, and some "things" will happen out-of-the-box, which is very confusing for a new developer on this project.
It loooks wasted time and efforts to write these classes yourself, but it only because your app doesn' have a complex database and/or business logic yet.
In short - the "standard" way provides much bigger flexibility at the price of writing repetetive code in the beginning.
You have much more control building the full stack on your own, you are using DTO's instead of returning the entity objects, you can combine repositories in your services and you can put your business logic on the service layer. If you are not doing anything of the above (and you don't expect to in the near future) there is no need for writing all that boilerplate yet over again, and that's when Spring Data REST comes into play.
This is an interesting question.
Spring Data Rest provides abstraction and takes a most of the implementation in its hand. This is helpful for small applications where the business logic resides at the repository layer. I would choose this for applications with simple straight forward business logic.
However if I need fine grained control (eg: transaction, AOP, unit testing, complex business decisions etc. ) at each of the layers as you mentioned which is most often needed for large scale applications I will prefer writing each of these layers.
There is no thumb rule.

Create A Service And Allow Only One Bundle To Hold That Service At any Time

I'm trying to create a service such that once it is created it only allows itself to be held by a single consumer/bundle at any one time. (If this is against the philosophy/specification of OSGi then that obviously provides a quick answer but reference to the OSGi specs. stating this would be appreciated.)
To implement such a requirement I implemented the ServiceFactory interface thinking that whenever there was a requirement for the service the getService(Bundle bundle, ServiceRegistration<S> registration) method would be called and it would be where I could determine if the Bundle was a new consumer or not and act accordingly.
It appears that this is not the case in the scenario I have tested this in.
Using a Apache Karaf and instantiating a consumer of the Service via Blueprint it would seem that the getService method is never called. Instead the consumer's binding method for the service is called directly but injecting a proxy service object.
While I understand that Blueprint uses proxies surely there is still the obligation of the ServiceFactory contract to fulfil even if it's a proxy object consuming the service?
Why do I want to do this?
I am attempting to wrap JavaFX and the Stage class and because JavaFX isn't OSGi friendly I am attempting to co-ordinate access to the Stage object. I'm aware that there are frameworks such as Drombler but a brief look at them made me think that it doesn't suit my use case. They appear too restrictive for my needs e.g. I don't necessarily wish to layout an application in the manner Drombler uses.
It depends what you mean by a consumer. ServiceFactory does give you the chance to create a separate instance of a service per bundle that calls getService on your service. It's not clear from your question but I suspect you weren't seeing the getService invoked multiple times because you were fetching the service from the same consumer bundle. In this case, ServiceFactory simply returns the same object repeatedly.
As for your general question about restricting access to a single consumer, no that really goes against the OSGi philosophy. I'm sorry I don't have a spec reference for you but the clue is in the name: it's a service that is available to all.
I'm aware that there are frameworks such as Drombler but a brief look at them made me think that it doesn't suit my use case. They appear too restrictive for my needs e.g. I don't necessarily wish to layout an application in the manner Drombler uses.
Please note that the layout of Drombler FX applications is pluggable so you can provide your own implementation tailored to your needs. This allows you to get the most out of Drombler FX and JavaFX.
While this feature is available for some time, there is now a new tutorial trail explaining it in more detail.

Spring Data Rest modify Repository method URI

This may be a bit of a rudimentary question, but I have a repository where I can do a find by username as follows:
....../items/search/byUsername/?username=myusername
However, this is generally inconsistent with how AngularJS Resources treat queries. Is there a way to instead make the request URI for the same thing to be
....../items/?username=myusername
Or does that functionality not exist with spring data rest? custom methods can be made in the angular resource but it is tedious to do that for every possible search category
If Angular (read: a client library) defines what URI's have to look like, then it's fundamentally violating a core REST principle — which is that clients follow links and URI templates.
That said, if you're using Querydsl and let your repository extend QuerydslPredicateExecutor, collection resources can be filtered by using property expressions. See the reference documentation for details.
Another option would be to manually expose resources under the URIs expected and manually forward the calls. But again, I'd argue you're better off teaching Angular to behave like a proper REST client in the first place 🙃.

How do I Integrate Entity Framework with External REST Data Source?

I am creating my first ASP.NET MVC 3 application, and my data comes from a data source I can access only via its REST API.
I will only be using READ-ONLY access at this point to the REST data source (no updating, etc.)
I would like to use the Entity Framework V4 to provide a Business Entity interface to MVC 3 without exposing it to the REST API.
I need to get something working quickly - so I don't have time to fully understand the Server Layer / UnitOfWork and Repository patterns just yet, although I plan to go there next.
I am willing to use a Repository class at this time, but not ready for DI / IoC container yet.
Any suggestions on where the RESP API calls go?
EDIT
Learned by asking this question that it is not necessarily useful to integrate an ORM with a REST API - See my accepted answer below.
An Object/Relational Mapper, or ORM, like Entity Framework has specifically been developed to abstract away a relational database. It might not be the right fit for REST calls.
You could instead build a repository class that encapsulates the REST call and exposes methods like IEnumerable<T> GetAll() or T GetyById(...).

Resources