How to reduce or organize swagger declarations with Kotlin - java

how can I organize the swagger annotations, for example I have an endpoint that catches all the users, so the swagger statements were huge. Is there any way I can organize this in another file to be more organized?

One of strategies often used is creating an interface (e.g. PersonApi in your case) and moving all swagger annotations there. The actual controller should implement this interface.
In regard to the error responses: you may consider adding them programatically to all operations/endpoints using OpenApiCustomiser.

Related

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.

Add additinal functionality to existing methods

I have a web application in Servlets and JSP. Now i need to add some additional functionalities to a couple of service methods in it. Service methods those needs these changes are from different servlets.
Additional functionalities are as follows.
Validating status before its core function.
Notify respective users on successful completion of that process.
How can I inject these functionalities to existing code with minimum overhead?
I think AOP in spring can help here, but i cant use Spring in existing application for this feature.
Also tried to use decorator pattern, but i couldn't as each service class contains multiple methods, also there is no common interface for them.
Can someone let me know how to handle this change in a better way.
Also tried to use decorator pattern, but i couldn't as each service
class contains multiple methods, also there is no common interface for
them.
As you are stating that there is no common interface, you can use Adapter Pattern which is the best fit when you have problems with service interfaces. Basically, adapters help to interact with two services with no common interface. You can create an adapter (layer) which handle the additional functionalities (i.e., Validating status and Notify respective users, etc..) by invoking the existing services.
Below is the wikipedia definition for adapter pattern:
the adapter pattern is a software design pattern (also known as
Wrapper, an alternative naming shared with the Decorator pattern) that
allows the interface of an existing class to be used as another
interface. It is often used to make existing classes work with others
without modifying their source code.

Using an Annotation Processor to create a list of classes with a certain annotation

I have a custom annotation that I've implemented and I'd like to use an annotation processor to generate a list of all the classes in my app that use that particular annotation.
I've found this tutorial which describes how to generate a class file using an annotation processor, so it should be quite easy to generate a class for each class with my annotation.
What I can't figure out is how I can collect all of that information into a single class. There doesn't seem to be a way to modify a class, so I can't append new items to the list once the class has been generated the first time.
Is there a way to use an annotation processor to generate a method that will return the list of all classes in an app that are annotated with a particular annotation?
Generated classes do not necessarily have to correspond one-to-one to the input classes being processed. Plus, you can search for classes (Elements) that are annotated with a given annotation via the RoundEnvironment:
roundEnvironment.getElementsAnnotatedWith(MyAnnotation.class)
From this you can generate a single class with a method that returns a collection of the classes found.
A couple issues around this to highlight:
Annotation processors can run along with other annotation processors and thus have to deal with classes generated at compile time. To aid this, Java annotation processing is performed in rounds to allow processors to catch the outputs of others. To be compatible with other processors you need to gracefully handle the ErrorType.
Only classes in the current compilation pass are returned from the RoundEnvironmnet methods so classes in external libraries will not be included.
IDEs (cough cough Eclipse) implement the annotation processing facilities of Java differently which can be a problem for processors that require a full non-partial compilation like I've described.
Coincidentally, I created a similar project recently that does what you are looking for:
https://github.com/johncarl81/silver
Silver is very much a WIP and uses a lot of library code to accomplish the task, but it may give you an idea for what's possible.

GWT - Mark parts of shared code as "server only"

I have a GWT app which contains, besides traditional "client" and "server" packages, also a "shared" package, which contains POJO DTOs that travel back/forth through RPC. I need to create some methods in those DTOs which should exist only on server-side (i.e. they should not be compiled to JS, because they'd use code which is not compile-able to JS), especially the static() method.
Is this possible in GWT (some attribute, ifdef, ...)?
Background:
I have some generic validators which require "registration" of the class to be validated (via a static method register(Class<T>), and since I can't find any GWT init() method I'd put the registration in static constructors of the DTOs, so when (if) the class gets loaded it registers itself for validation.
A detailed discussion of this issue:
http://code.google.com/p/google-web-toolkit/issues/detail?id=3769
We had some similar issues with some DTO objects in a project recently. We ended up splitting the data away from the methods, creating a second set of classes that contained static methods for dealing with the data. As far as I can tell, there isn't any way to annotate methods in a class to prevent gwtc from trying to convert them to javascript.
It seems that Google implemented it in r11570.

Dependency Injection With Annotations

I would like to build my own custom DI framework based on Java annotations and I need a little direction to get started. I know it would be much easier to use one of the many wonderful frameworks out there such as guice or spring, but for the sake of my own curiosity, i'd like to build my own.
I'm not very familiar with annotations, so i'm having a bit of trouble finding resources and would really appreciate someone just sort of spelling out a few of the steps i'll need to take to get started.
As fore mentioned, id like to take a factory approach and somehow label my getters with an #Resource or #Injectable type annotation, and then in my business classes be able to set my variable dependencies with an #Inject annotation and have the resource automatically available.
Does anyone have any sort of resource they can pass along to help me understand the process of tagging methods based on annotations and then retrieving values from a separate class based on an annotation. A little direction is all I need, something to get me started. And of course i'll be happy to post a little code sample here once I get going, for the sake of others future reading of course.
EDIT
The resources I am using to put this together:
Java Reflection: Annotations
How to find annotations in a given package: Stack Overflow ?
Scanning Annotations at Runtime
I have not actually finished writing this yet, but the basic task list is going to be as follows (for anyone who might be interested in doing something similar in the future)
At class runtime scan for all #Inject fields and get object type.
Scan all classes (or just a specific package of classes (I haven't
decided yet)) for annotated methods #InjectableResource.
Loop all annotated methods and find the method that returns the
object type I am looking for.
Run the method and get the dependency.
It will also be helpful to note that when scanning all the classes I will be using a library called Javassist. Basically what this does is allows me to read the bytecode information of each class without actually loading the class. So I can read the annotation strings without creating serious memory problems.
Interesting that you want to build your own. I love Google Guice - it makes code so elegant and simple.
I've used this guide before which I found pretty useful for learning about annotations and how you can pull them out of classes and methods.
You will have to define your own Annotations which is done using #interface. Then you will have to define some kind of class for doing bindings e.g. where you see an interface bind in this concrete class. Finally, you will need some logic to pull it altogether e.g. go through each class, find each annotation, and then find a suitable binding.
Give consideration to things like lazy instantiation through Reflections and singletons. Guice, for example, allows you to use a singleton so your only using one instance of the concrete class, or you can bind a new version each time.
Good luck!
Have a look at the following methods:
java/lang/Class.html#getAnnotation(java.lang.Class)
java/lang/Class.html#getAnnotations()
java/lang/Class.html#getDeclaredAnnotations()
Methods of the same name also exist for the java/lang/reflect/Method, java/lang/reflect/Field and java/lang/reflect/Constructor classes.
So in order to use these sorts of methods, you need to know a bit about Java reflection.

Categories