I have a bunch of RestController classes which look something like this:
public class CategoryController {
private final IModelService modelservice;
private final ICacheHelper cacheHelper;
public CategoryController (IModelService modelservice, ICacheHelper cachehelper) {
this.modelservice = modelservice;
this.cachehelper = cachehelper;
@GetMapping("/foo/bar")
public ResponseEntity<Model1> getModel1 () {
Model1 model1 = modelService.getModel1();
if (model1 == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok().build();
}
@GetMapping("/foo/bar/baz")
public ResponseEntity<Model2> getModel2 () {
Model2 model2 = modelservice.getModel2();
if (model2 =? null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok().build();
}
}
So I created a Base.class which contains the following
public class Base<T> {
private final ICacheHelper cachehelper;
public Base(ICacheHelper cachehelper) {
this.cachehelper = cachehelper;
public ResponseEntity<T> simpleResponse(T object, CacheControl cacheControl) {
return object != null
? ResponseEntity.ok().cacheControl(cacheControl).body(object)
: ResponseEntity.notFound().cacheControl(cacheHelper.getErrorMaxAge()).build();
I then extended the CategoryController with Base but without generics. So I could use my simpleResponse. Rightfully I get lots of warnings of unchecked assignments in IntelliJ. The more i read about generics the more i understand that this is simply not a good idea and only possible because of legacy reasons.
Has anyone an idea how to do this better and use generics the proper way? I thought of restructuring the RestController, and make them based on the returnValue. Which means that I need to create for every Model that I want to return a extra ControllerClass. Then I can i.e.
public class Model1Controller extends Base<Model1> {
// do stuff
}
Is this a good API design or do you guys have other ideas to solve this problem. Another idea was instead of extending a Base.class I could do some kind of util class with static Methods. But I need to check this out first
You simply remove < T> from Base class and move < T> into the generic method. It will remove the warnings of unchecked castings:
public class Base {
private final ICacheHelper cachehelper;
public Base(ICacheHelper cachehelper) {
this.cachehelper = cachehelper;
}
public <T> ResponseEntity<T> simpleResponse(T object, CacheControl cacheControl) {
// ...
}
public <A> ResponseEntity<A> anotherSimpleResponse(A object, CacheControl cacheControl) {
// ...
}
}