Rest API Request Object as empty abstract or interface? - java

Trying to figure the best design for my api where all calls will take in a base form of a request. The response will be very similar for all the calls.
Some requests will inherit some properties while others will not. All the calls will funnel through the same service so the base request will be what the main service takes in.
I.e.
public Response mainServiceHandler(BaseRequest request)
My question is what are people's thoughts on an empty abstract BaseRequest vs an empty interface BaseRequest? Any advantages of one over other in terms of an api? I thought an interface would always be the best manner since it is more flexible in design but wasn't sure if it applies in this case. Not too familiar with Marker interfaces but the little I read it didn't seem to be the best solution for this or does any implementation really makes much if a difference here.

Related

Java- How is using an interface for callbacks advantageous?

I am trying to get a grasp on the concept of using interfaces for callbacks and I feel that I have a basic understanding.
I was introduced to interfaces through the example of processing data in a collection--you can iterate through a collection of Interface objects, and each element in the collection implements that Interface in its own way.
However, I am now learning that this has some limitations, including that Library classes cannot implement the methods (what others?). How do callbacks solve these limitations? (I understand how it solves the problem I described). Thanks for the help, having a tough time really grasping this.
How do callbacks solve these limitations?
They mostly don't.
We use callbacks when we have an asynchronous interaction pattern; for example, if we want to send an HTTP request without tying up our thread, then we need a callback to handle the response when it comes.
In such a situation, we're willing to put up with the awkwardness of these limitations.
(Keep in mind that none of the limitations mean "X can't be done". For example, you write that "Library classes cannot implement the methods", which is true, but it's easy to write a callback object that operates on another object. Java 8 has made this even easier than it used to be; something like (response) -> responseList.add(response) is a complete callback object that saves the response into the existing responseList.)

Is it a bad idea to use #RequestMapping in interface?

I checked out this SO Post which discusses using RequestMapping in interface. Although the post contains ways to achieve this but it does not mention the pros and cons of doing this.
Architecture wise , is this a bad idea to use controller as interface?
What benefit will we achieve in terms of polymorphism for controller?
There is nothing wrong with putting #RequestMapping on the interface. However make sure you have the right reasons to do it. Polymorphism is probably not a good reason, you will not have a different concrete implementation swapped in at runtime or something like that.
On the other hand, for example, Swagger codegen generates interfaces with #RequestMapping and all the annotations on the methods, fields and return types (together with #Api definitions etc.). Your controller then implements this interface. In this case it makes a lot of sense because it is just enforcing you to respect the Swagger / OpenAPI interface definition originally defined in Yaml. There is a nice side-effect that it makes your controller much cleaner. (Clients can also use the same Yaml to generate their own client stubs for their own language frameworks).
If you opt to do this, make sure you use the latest version of the Spring Framework, because there were some bugs which were fixed only very recently, where not all annotations were being inherited.
https://github.com/spring-projects/spring-framework/issues/15682
If you are stuck with an older Spring version, you might need to repeat the same annotations in your controller.
So, the real reason this would make sense is to enforce the interface contract, and separate the interface definition (together with any information pertaining to the interface) from the actual concrete implementation.
While some arguments against this are that
the request mapping is an implementation detail, or
since you only have one active controller implementation, you might as well put it on the implementation,
(others will probably be provided in different answers soon,)
I was recently faced with the same decision to put jax-rs annotations on the interface or the implementation. So, since everything always "depends" on some context, I want to give you an argument for putting the RequestMapping (or e.g. #Path, etc if not using spring) on the interface:
If you are not using HATEOAS or discovering the endpoints via some other means, the endpoint url, http method, etc. are usually fixed and a static part of your backend API. Therefore, you might as well put it on an interface. This was the case for me because I control both the client and the server side.
The controller usually has only one active implementation, so the reason for doing so is not polymorphism. But your implementation usually has a lot more dependencies than the plain interface. So if you export/provide only your interface to clients (e.g. in a seperate jar/java project/...), you only provide things that the clients really require. In my specific case, I delivered the annotated interface so that a client implementation could can it using a Rest-Client-Library and detect the endpoint paths automatically.

Is "Facade design pattern" and Java interface conceptually same?

Is "Facade design pattern" and Java interface conceptually same ? As both achieve abstraction by providing simple way of expressing a complex functionality.
Can we say by creating interface we followed Facade pattern ?
No, I's not the same.
For implementing Facade design pattern is not necessary to implement any interface. It just provide a new layer to communicate to your services, as an example.
class ServiceFacade() {
private Service1 service1;
private Service2 service2;
public void update(Entity entity){
service1.update(entity);
service2.update(entity);
}
}
So it will give you one point to communicate with all services that are related. Instead of calling service1.update() and service2.update() you just call facade.update(), so you are sure that both services update the entity.
One more example: maybe all the time service is updated you need to refresh() you cache. This also can be incapsulate in your Facade:
public void update(Entity entity) {
service.update(entity);
cache.refresh();
}
If your facade class has only one dependency, but you want to extend the functionality of this dependency, you can achieve that by implementing Decorator pattern. Here is where you do need to implement the interface.
Let's take a look at the following example. Suppose you have a service and you want to extend it with a simple cache
class CachedService implement Service {
private Service service;
CachedService(Service service, Cache cache){
......
}
......
private Entity get(Long id) {
Entity cachedEntity = cache.get(id);
if (cachedEntity != null){
return cachedEntity;
}
return service.get(id);
}
}
Façade is a conceptual design pattern. There's no specific interface nor implementation.
It's just an additional layer on which you implement operations that otherwise would force upper layers to understand and be coupled to irrelevant implementation details for themselves.
For example, a façade method could be a credit card payment process on which you need to send many requests and process their responses to store the billing result on some database.
Without a façade method, every part of your system on which you need to perform a payment using a credit card would need to repeat those 5-10 code lines all over again. At some point, you find that you need an extra step when performing those operations and you realize that you need to refactor thousands of code lines. That is, your solution could have a security hole and you won't be able to respond to the security treat in time. A façade can make the difference from being a poor software provider to being a serious and robust one!
In the opposite side, when you implement proper façades, when some layer needs to perform a credit card payment it just injects a billing façade and it stays agnostic about how the billing process is being made hence you don't repeat yourself in many parts of your system and refactoring isn't a tedious and time-consuming task.
While façade pattern doesn't define an interface per se, façades should be defined as interfaces, since they can also act as proxies: an implementation could make use of the service layer directly and other might call a RESTful API to perform the same task, depending on who needs the façade itself.
Anyway, this design pattern isn't specific to simplifying a given service layer. You might consider a façade method a method that may simplify a complex string manipulation involving many regular expressions, replacements and insertions.
Facade hides the complexity of the system and provides an interface to the client from where the client can access the system, meaning that Facade hides low-level functionality from client.
Will that interface be java interface it is up to you.
Good question. I was once asked in an interview what design pattern an Interface represents, and my best guess was Facade. I don't really know what the interviewer was trying to get at, though.

Synchronous and Asynchronous method in an Interface vs in a Class?

I am working on a project in which I am supposed to make a client and the role of that client is to construct a url basis on input passed and make a REST call on the right server.
And they can do it in two ways, either making a synchronous call or making an asynchronous call. So now I am not sure what is the right way to do this?
Should I make an interface for this with two methods synchronous and asynchronous method and a class that will implement this Interface or should I just make a simple class with these with these two methods inside that?
What is the better approach?
I would not put both methods into the interface, just the synchronuous one.Then imagine N different implementations which really only care about getting the data. All of them can likely be wrapped into a single asynchronuous wrapper class. No need to force each implementation to reinvent the asynchronuous behaviour.

Tightly Coupled classes: what is better design in my situation

what is the better solution in my situation, how to design classes so they are not very coupled?
I have an Library (API) which provides some functionality (for example, subscribe for streaming FX prices with subscribe method). I have an API client, which tell to API which prices it want to get. API provides feedback with some interface (for example SubscriptionStatus) with methods SubscribeSuccess(Subscription) and SubscribeFailed(Subscription). In API client I have a list of active subscriptions (List<Subscription> activeSubscriptions). And I want API client only react on subscription success (just add subscription into list). In other cases - just print message to log.
What is the best way to organize relations between Subscription listener and API Client?
Options could be:
Pass API client instance to the subscription listener so it can call apiClient.addSubscription(subscription)
API client implement implement SubscriptionStatus interface and manage those events (fail, success internally: activeSubscriptions.add(subscription)). Contra: There are a lot of types of actions and every action has it's own listener.. So Api Client will be really big class.
Define own interface with one method SubscriptionSuccess(subscription) and let API client implement it?
Your option?
Any thoughts on topic are appreciated!
Thanks!
I would go option 2, with a catch. If the SubscriptionStatus interface is really really big, and you know some clients only want to implement part of that, you can provide a base empty superclass, and you let clients extend it (make it abstract to force them)
Something like BaseSubscriptionStatus that has empty implementations for all methods, and let the user override the ones it wants. Another option is to
throw UnsupportedOperationException("This method is not supported by your implementation of SubscriptionStatus. Please override it");
for each base method instead of the empty implementation.
Of course, you can keep the SubscriptionStatus interface for proper dependency injection and testability, only make BaseSubscriptionStatus implement it.
I would go with option two. This would give the end use the most flexibility and be able to respond to issues with the streaming more effectively in their situation.

Categories