I would like to generate the Swagger documentation for an existing JAX-RS implementation without having to modify my code at all. I'd love not to have to introduce any kind of Swagger annotations decorating my classes.
Here
https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-JAX-RS-Project-Setup-1.5.X.
they seem to suggest that after configuring your application to use Swagger you have to annotate your code for swagger to be able to generate swagger.json. Am I right? Are annotations needed? If not, I don't understand very well their purpose
Is this magic of documenting your existing JAX-RS application without modifying you code possible?
I've found this http://www.adam-bien.com/roller/abien/entry/jax_rs_get_swagger_json.
Could this be a solution?
Swagger annotations are required to add the documentation to your JAX-RS implementation. The purpose is to define your API operations and parameters, what is their meaning and purpose.
The link you shared appears to be some sort of a hack mechanism. But i don't see how any code can find out the intent of your API unless you explicitly declare it.
If you need to minimize swagger annotation usage, there are 2 ways to do this:
Only use #Api at class level and do not use method level annotations. This will render a basic swagger.json with a listing of your GET/POST etc APIs.
Write an interface and use annotations here. You API class needs to just extend this interface then. This will reduce impact on your existing class.
Hope this helps.
Related
I want to intercept a whole class with java standard features, because i am not allowed to add new dependencies to the project (websphere 85).
I want to call a function, which does multiple api calls (swagger generated) for example myapi.bla(), myapi.blabla(), etc and get the headers from the response.
I thought about intercepting all methods of the class "myapi" and then access the headers (myapi.getApiClient.getResponseheaders).
Do you know how to intercept all methods of a class with java or websphere85 built in features?
Thank you!
There are prominently 2 ways to achieve this,
AOP, you can use AspectJ to achieve this which basically modifies the class to inject interceptions, either at compile or load time. Example.
Dynamic Proxy. A good explanation on how to use it with example. Though it comes with a performance cost.
Can we use spring HATEOAS on top of RouterFunction ? I imagine that we can specify the resource but what will be the equivalent of the linkto(Controller.class) ? or is there any equivalent to specify the link and use composition of RouterFunction
By definition, you're creating a custom route and Spring HATEOAS is an opinionated set of frameworks meant so you don't have to lift a finger. What you are trying to do, and what Spring HATEOAS is doing are contradictory. So, you will have to manually create the payload if you want embedded hyperlinks.
Although, this shouldn't be too difficult if you set your owner content handler for your specific return type on that route.
Answer in January 2023: not yet.
Spring HATEOAS was originally built with Spring MVC in mind, so even WebFluxLinkBuilder relies on Controller annotations to build the resource links.
The RouterFunction interface has no methods that expose the underlying RequestPredicate, so there is no way to determine which path is associated with a given RouterFunction. Some method may be introduced in a future API to provide the needed access to that information out-of-the-box, without having to do something nasty like breaking encapsulation with Reflection. In the meantime, you'd probably need to consider centralizing all relevant RouterFunction creation (e.g. via a helper/util/custom builder class), so you can intercept all paths and the associated HandlerFunctions with some degree of confidence.
Yeah, when you use RouterFunctions, unfortunately Spring HATEOAS does not help creating the links, and it is challenging to reliably implement this functionality in a generic way based on the current WebFlux functional API.
I am adding swagger 1.5.0 support to an existing java application that implements 20+ different REST APIs and uses Jersey 1.17.1 with package scanning. Does anyone have any best practice recommendations? For example:
Should swagger definitions be added to each java class or can they be
added to an independent file(s) to avoid touching each class?
Each API requires the same set of headers which I have defined in great details for the first class using #ApiImplicitParam. Instead of
repeating that information for every operation of every class, is
there a way to apply it to all APIs?
There are a zillion ways to integrate the swagger 1.5.x libraries (note: 1.5.10 is latest) with a JAX-RS application. I suggest you follow a scheme like in the swagger-petstore and split the files by top-level path segments, which should provide a logical organization.
For repeated headers, you can have each resource class extend a base class which has an annotated class-level variable. That will apply to each operation in the classes that extend it.
When I was going through spring core related document, I came across concept called "Inheritance based proxies".
Can anyone please explain a bit on this. It will be nice if you can show some
code samples.
Thanks
There are two types of proxies available in Spring:
JDK proxy, which comes out of the box in JDK and CGLib, which is created by the CGLib library (3rd party dependency).
JDK Proxy only works with beans that implement an interface and it is also the Spring recommended way of using AOP.
However, there are lots of scenarios out there where you would have to code concrete classes and therefore must use CGLib. CGLIB proxying works by generating a subclass of the target class at runtime. Spring configures this generated subclass to delegate method calls to the original target: the subclass is used to implement the Decorator pattern, weaving in the advice.
I think that's what is being referred to as 'inheritance based proxy'. http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop-api.html#aop-api-proxying-class
I'm looking for a way to add certain functionality to JAX-RS resources in an OSGI environment. Annotations seem to be a clean way to do this and I've seen it done in the Spring framework (no experience). Annotations such as #Transactional, or (what I wanted to do, requires a permission flag to be set on a user) #Permission(CREATE). However, I'm a bit stuck on how to do this in an OSGI environment.
The normal way(is it?) to go about adding aspects would be to register an aspect service that wraps the original service. If I looked it up correctly, JAX-RS resources are tracked and hooked up to an HttpService. JAX-RS resources do not implement an interface and proxies would need to be dynamically created.
How would I dynamically generate OSGI aspect services/resources that effectively hide the original resource from the JAX-RS tracker that hooks it to the HttpService? I have zero experience with existing AOP frameworks and barely any knowledge of AOP itself.
It is very common in the Java EE and Spring world to use interceptors and define additional behavior based on annotations. There are some solutions in OSGi as well, there is an RFP to support EJB annotations.
However, I have a different opinion. Although this looks cool, it is also magical. See the "Why not annotations, interceptors and other magic?" chapter of this README file where I wrote down my reasons. This project implements the logic that you would like to achieve with #Transactional annotation, but it only uses functional interfaces.
I think it is better to think in lambda expressions to achieve the goal you want (see the java 8 example behind the link). If it is not Java 8, you can still use anonymous classes (see jave 7 and above example behind the link). Your code will look more ugly with anonymous classes, but it will be very clear, what your code does.
Others might not like my answer. Three years ago I was one of the biggest fan of annotation scanning, weaving and interceptors. After a couple of headaches, I became an enemy of this "magical" concept.