3

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?

tryingToLearn
  • 10,691
  • 12
  • 80
  • 114

2 Answers2

8

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.

jbx
  • 21,365
  • 18
  • 90
  • 144
4

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.
sfiss
  • 2,119
  • 13
  • 19
  • Another good example of this is having contract first service interfaces generated with Swagger / OpenAPI codegen from Yaml. – jbx May 17 '19 at 07:42