0

Little Java design question here (for what matters it is in a context of a JEE Web Application).

Let's say I have a REST API with two operations : GET and POST on the same ressources. From there, using Jackson two classes are constructed representing the request's input fields. Those classes are different because the requests' parameters vary a little bit.

Let's say those two classes are named GetRequest and PostRequest.

Those two classes contains a set of fields that are common. And a set of fields that belong to each class. For instance :

public class GetRequest {

   // common fields
   private String callerId;

   private String userId;

   // non-common fields
   private boolean withLinkedServices;

   // Constructors, egals, hasCode, toString, getters,setter etc...
}

And for class PostRequest

public class PostRequest {

   // common fields
   private String callerId;

   private String userId;

   // non-common fields
   private List<ServicesBean> services;

   // Constructors, egals, hasCode, toString, getters,setter etc...
}

In the business layer of my application, I have to code an helper method (for each REST operations) which will fill another bean using common fields of each objects. The implementation of this method is exactly the same for the GET and POST operations.

The only thing that vary is that in the case of the GET operations I have to pass the GetRequest class and for the POST I have to pass the PostRequest.

So my question is :

Should I work on the data model and use inheritance or should I use Generics in my helper method ? Which one would make more sense and be more efficient and resilient to application's future evolution (in case more operations are added on that ressources for instance) ?

The signature of my methods is (for the helper of the POST) :

public IDaoRequestBean buildDaoRequest(final PostRequest request);

And for the helper of the GET :

public IDaoRequestBean buildDaoRequest(final GetRequest request);
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
anchnk
  • 291
  • 1
  • 5
  • 19

3 Answers3

1

Using generics is not really needed. You would need to have both classes implement a common interface, so you can call getCallerID/getUserID. But having them both implement a common interface, would remove the need for generics:

interface IRequest {
    String getCallerID();
    String getUserID();
}
/* Overcomplicated, with generics */
public <T extends IRequest> IDaoRequestBean buildDaoRequest(final T){...}

/* Using just the interface */
public IDaoRequestBean buildDaoRequest(final IRequest){...}

So you're pretty stuck with inheritance.


Using an abstract class instead of an interface has the added benefit of not having to redeclare fields and getters. With the limitation that you can't extend any other class.

abstract class BaseRequest {
    private String callerId;
    private String userId;

    // Getters
}

class GetRequest extends BaseRequest {...}
class PostRequest extends BaseRequest {...}
/* Pretty much the same here... */
public IDaoRequestBean buildDaoRequest(final BaseRequest){...}
Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
0

I believe inheritance would be the way to go. If you end up having new requests, having generics could mean that you could pass a type of a request that possibly wouldn't match the implementation of a method unless they extend the same class, which would lead to inheritance, isn't it? By having only requests of a type POST and GET's superclass, you limit it to the two of them. Please correct me if I'm wrong.

Memfisto
  • 322
  • 1
  • 10
0

In my opinion, you should not have GetRequest as your request body for the get method call. The get rest call should be based on Id(example: employees/id). For some reasons if you are having an object in the request body, then follow the inheritance in your class hierarchy but be specific on your class type in both the rest and the helper method implementation methods because

  1. In the future, you may have to add a new common attribute so this model gives you flexibility.

    abstract class AbstractRequest{ //Common attributes }

    class GetRequest extends AbstractRequest{}

    class PostRequest extends AbstractRequest{}

  2. Also in the rest model arguments and helper class method arguments, if you don't define the specific child type as parameters, another developer can call your helper class with any child type of the argument. This can break your functionality. So be specific on the argument type in the helper and rest methods.

    GET -> method(GetRequest)

    POST -> method(PostRequest)

    public IDaoRequestBean buildDaoRequest(final PostRequest request);

    public IDaoRequestBean buildDaoRequest(final GetRequest request);