WS to Service concern - java

I have a Rest layer that call the Service layer.
My language is Java with Spring Framework
With some code would be:
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Entity get(#PathVariable("id") Long id) {
Entity entity = new Entity();
entity.setId(id);
return entityService.get(entity);
}
Well.... here are my questions:
Is it better to have a generic method in Service layer to hold the
parameters and filter to get and etc?
Is it better to have unit methods to filter the get like:
entityService.getByID(id);
entityService.getByValue1(value1);
entityService.getByIDAndValue1(id, value1);
Is it better to set the properties of Entity at Rest layer and call
service passing an object?

I think you may have some separate methods for more frequent use cases, like findByPrimaryKey(id) or findByName, and also a find by example method that will find entity by all not null fields in given entity.
You can also define a Business aware query interface (i mean no database layer query) to find objects, But this will complicate your rest service layer code so i prefer separated and simple methods that will make your service layer more readable.
There is also a Parameters Object design pattern, that mean grouping logically related parameters in object, eg. start date and and date as DateRange object.
But is useful when some logically related sequence of objects are passed as parameters to various methods. For example contact parameter may contain address, Zipcode and tel.

Related

How to create a field of data type varchar in controller class

How do I create a field of data type varchar in my controller class with size as 20?
Also, could anyone please tell me how to create a field of data type none. Also, how to mention the fields to be mandatory?
I am quite beginner in this. Any help would be appreciated.
you cannot declare varchar in controller you have to use String
private String str = ""; or you can use this
StringBuilder str
= new StringBuilder();
str.setLength(20);
Ok, so your question is lacking context so I am going to make some assumptions. I'm assuming that you have to implement some controller that exposes an URL endpoint. I assume that you want to be able to receive data on that endpoint and map it to an object (dto). I assume that you want to assure that you want to perform validitions on the received data.
Im on my phone so I won't write it out completely but let me give you some pointers.
Create a dto object with the data structure that you're expecting to receive.
Create a contreoller with #Controller annotation.
Within the controller, create a method with the #postMapping annotation and configure it appropriately. The method should accept the dto class and a binding result class as method parameter. Within the method definition use the #Valid annotation before the dto class. The informs Spring to validate the dto and it will inject the valdition result into the Binding Result object. Note that the latter should be mentioned after the dto, in this example it would be the second and last parameter.
Now in the dto, you can annotate the class fields with annotations from the javax.validation package. For example #NotNull or #Size which could assert the size of a string field and assure the availability of a field value. Note that I believe in later versions of Java, the validation package was moved to Jakarta package so take that into consideration. Also make sure to use the right annotations, for example there is also #Nonnull from spring which does other stuff.
Now, within the method body you can now assert if there where any binding result errors. Just check the BindingResult.hasErrors() and then handle them appropriately.
The field of data type None does not ammake sense to me so will need more information to be able to help with that.

Is it good practice to pass collection name in Morphia createQuery method?

I usually use this approach while instantiating the query object:
Query<Product> query = datastore.createQuery(Product.class);
But Morphia allows you to pass the collection name also while instantiating the query object, which would look like this:
Query<Product> query = datastore.createQuery(COLLECTION_NAME, Product.class);
I am unable to understand why do we have to pass the Collection name explicitly while creating the query object?
When we create the model, in this case in the Product class we are already binding the collection name under the Entity annotation:
#Entity(value = "product", noClassnameStored = true)
class Product {
// model attributes declared here
}
One reason I can think of is, if the same model is used across multiple collection then we might need to pass the collection name, but even if it is so is this a good practise and does it abide the ORM guidelines? Please help me understand.
That method is used for cases where one entity is stored in different collections depending on the application usage. It's "hidden" on the AdvancedDatastore interface so that all you should see on a Datastore reference is the one createQuery() that takes the type. Most users won't need the overridden form but it was added years ago as a convenience for those who needed to map to multiple locations.
It's a mild misfeature as it doesn't quite work well with #Reference fields. I'm not sure how long that feature will continue to exist as it complicates some of the implementation for very little benefit.

Inheritance and REST API Controllers - Dealing with Subclasses

I have the following class hierarchy for Coupon and Deals platform am developing::
Promotion - abstract
- Coupon
- Sale
- Deal
(Coupon, Sale and Deal inherit from Promotion. Promotion has a string attribute called type and an abstract method that initializes the the type attributes of the subclasses to a string value. For instance the type in coupon gets the value "Coupon" etc...)
For each subclass, I have a DAO and Service classes like CouponDAO, CouponService, etc.
In the front-end users can create Coupon or Sale or a Deal through Angular 2 interface so I decided to have the following controllers:
PromotionController - abstract
- CouponController
- SaleController
- DealController
(CouponController, SaleController, DealController inherit from PromotionController )
The PromotionController will contain all the common CRUD functions common to all subclasses and in the specific controllers I will handle specific operations meant for those classes.
A) The issue am facing now is how to instantiate the correct object coming from the client side. For instance when a user submit a Coupon or a Sale or a Deal how do I instantiate the right object. For instance in the PromotionController I have a function like this::
#RequestMapping(value=CREATE_PROMO, method=RequestMethod.POST)
public ResponseEntity<?> create(#RequestBody Promotion promotion){
promotionService.save(promotion);
return new ResponseEntity<>("", HttpStatus.OK);
}
Promotion which is abstract is the argument of the function. Should I use the factory pattern and the **type** attribute to create the right object?
For instance if the type="Coupon" then I create Coupon object, if it is "Sale" then I create the Sale object
B) Since the controller uses the Services objects it means that I have to declare all the three services objects in the PromotionController. Because after instantiating the right object, I need to call its corresponding service to do the job. In the method above I have promotionService which I think should be replaced with the right service of subclass
C) I am looking for how to handle REST APIs that deals with subclasses in the real world like the situation I have described above
D) I was thinking of making it easy for myself by copying all the CRUD operations to their specific controllers but it seems that will be repetitive code.
I think there is a better way that can be done.
I have also tried if I can find an open source project that deals with this situations but it seems all the projects I found use one class and not inheritance. Their REST/APIs don't handle inheritance situations
In my view, keep your endpoints simple. From a REST API standpoint, create individual or only one controller and use the following patterns after the controller layer. From what I have seen, it is always better to keep REST endpoints away from inheritance/reuse and apply it later after receiving and validating the requests.
To instantiate service/helper layer from controllers, use factory method pattern:
https://en.wikipedia.org/wiki/Factory_method_pattern
Create a PromotionServiceFactory which returns the PromotionService implementation depending upon the promotion type.
In controller, invoke corresponding method of promotion service using the factory. The factories still accept arguments of type Promotion.
#RequestMapping(value=CREATE_COUPON, method=RequestMethod.POST)
public ResponseEntity<?> create(#RequestBody Promotion promotion){
//helper if adding one more helper layer. The factory invocation is then //transferred to the helper layer
PromotionService couponService = promotionServiceFactory.get(PROMOTYPES.COUPON);
couponService.save(promotion);
return new ResponseEntity<>("", HttpStatus.OK);
}
From your questions, it seems like that there are common CRUD/other methods for different promotion types. This is a good candidate of the template pattern in the service layer if some of the steps/sub-tasks are same for every promotion and the others vary. Otherwise, you could just store the common CRUD methods by creating an abstract promotion service.
https://en.wikipedia.org/wiki/Template_method_pattern
Create an abstract promotion service with the primary method and implementations of common CRUD methods. Create individual implementations of other promotion service types with respective varying methods.
I think you can handle this in two ways depending upon the logic.
If you want to keep everything Separate then create a difference endpoints for coupon/deal/sale. That way every endpoint will call its controller and so on.
2) If you think code is same that you can use abstract factory pattern to instantiate the correct service and DAO object.
It all depends on your business requirement, I would prefer the second way if code logic is almost same. One controller per inheritance, so that in future if hierarchy increases you do not need to create multiple classes until required.
to answer you (A), I think you could use requestObject.instanceOf() method, to tell the correct subclass type, then handle with correct handler.

Best approach for creating URLs in Spring

Let's say we have controllers with URL mappings like movie/{id}-{title}, actor/{id}-{name}, etc. These mappings identify some objects in our app, mostly entities - we can say it's a RESTful service.
I'm looking for a solution as to where I should put methods responsible for creation of those URIs. I think that creating them in multiple JSP files and some other places (redirection, etc.) is redundant.
First, what I thought about was creating some interface with method public URI getURI() that classes that will be used in controllers will implement. But, in my opinion, that would involve too much into entity - I prefer entities just to represent data and contain only methods to change state.
My second idea was to create a URIService with overloaded methods like URI getURI(Movie m) and URI getURI(Actor a), but there will be a problem with the choice of overloading method at compile time. For example, in EL in JSP that wouldn't work well, as the solution would be naming methods differently.
I don't want to reinvent the wheel, so maybe you know or use some solution to that problem?
How enterprisey do you want the solution to be? (I'm just half kidding)
Here's a solution: Have a service that has a method like URI getURI(Object o). This method will check if the object passed belongs to a class with an annotation that specifies the URI path. Example annotation:
public #interface PathTemplate {String value();}
Example class with the annotation:
#PathTemplate("/movie/{title}-{id}")
public class Movie {
private int id;private String title;
// getters and setters too
}
Now, the getURI method will see that the parameter object's class has a PathTemplate annotation and will interpolate the parameters using bean introspection. Voila! Expandable and relatively decoupled URI generation.

Design pattern to enhance an existing data structure in Java with additional information at runtime

I will start with a small example:
Imagine an application with a couple of entities.
EntityA -1---n-> EntityB -1---n-> EntityC
Let's say we have a service method that returns a list of EnityC instances. In the UI we want to display EntityC but also add some additional information to the entity that is only relevant for the UI (maybe a css class or so). A common way to solve this would be to create a wrapper arround EntityC that can also carry the additional information.
public class EntityCWrapper implements EntityC, AdditionalInfo { ...}
or maybe use a transfer object as simple data structure:
public EntityTO {
public EntityC entity;
public AdditionalInfo info;
}
But what if the service returns a list of EnitityA instances and we need to attach AdditionalInfo to all entities in the instance graph (including the referenced entity instances of EntityB and EntityC)?
Does anyone have an idea or can point me to a design pattern suitable in this situation?
Have a look at the Role Object Pattern.
It descripes how an object can be extended with different stuff (called Roles).
The pattern is more about how to add Bussiness Logic (that is why it is called roles) but may the idea helps you.
Assuming AdditionalInfo is instance specific (i.e. each instance of EntityC has a unique 121 relation to an AdditionalInfo instance) best option would be to enhance EntityC definition to include AdditionalInfo inside it as member/..., which is optional and filled up by you.
If you don't have control over EntityC then between teh two options you have given, I would say TransferObject seems better. You won't have to create new objects (of EntityC) that way.
So your data model is essentially 1 to n using the following object as an example (contrived as it may be)
class Thing
{
Collection<DooDad> dooDads;
}
class DooDad
{
Collection<DooDadDetail> details;
}
class DooDadDetail
{
...
}
So I would treat this as my model, in terms of n-tier architecture and therefore this should map back to my database exactly. What comes up is you want your model to do something, whatever that may be. So you should create an object that is composed of Thing that can interact with business logic or outside services. Creating a transfer object would be correct in this case as it ensures your model remains valid and that the interfaces between both you and the outside service are not dependant on your model. It is sort of a Facade pattern and a Data Transfer Object.

Categories

Resources