I am trying to incorporate swagger-codegen in my new greenfield project, using Java (jaxrs-jersey2).
There are a lot of resources out there already documenting various parts of the project; however, I still haven't been able to find out any high-level advice on the best workflow to use with these tools.
As I understand it, swagger-codegen will be able to generate client-side code to interact with my API, such that I don't have to write this myself. This will happen by looking at a swagger.yaml (2.0) or openapi.yaml (3.0) file. This part is clear.
However, there seems to be multiple ways of generating this specification file. As I understand it, there are two primary ways:
Write a server implementation using a combination of jaxrs and Swagger annotations - have a maven plugin run as part of the compile step, generating a swagger.yaml specification file to be used by the client-generation plugin.
Write a swagger.yaml specification first, and generate server-stub code for Jersey, implementing only business logic, separate from all server boilerplate.
Which of these two ways is the recommended workflow? It sounds like (2) means writing less code and focusing on just application logic, without worrying too much about Jersey-specific glue to make the API work. This also means that the single source of truth for the API becomes a simple yaml file, rather than a bunch of Jersey code.
However, I'm unsure how to properly set this up:
Does my build need to have a compilation phase where server stubs are constantly regenerated?
Do I simply extend from the generated server stub and never worry about annotating API paths with #Path, #GET, etc?
Am I misunderstanding the use-case for server-stub generation? I.e. is the first approach (Jersey code-first) more appropriate?
If there is no real difference between the two approaches, when would you pick (1) over (2) and vice-versa?
Many thanks.
Related
Are there any libraries out there that can generate the JSON/YAML file by analysing static code and generating the JSON/YAML files off of that?
Right now we're producing the Swagger files once the project has finished building. We hit the url at /api/swagger.yaml and do what we need with the file (this adds quite a bit of complexity to our automated builds)
Yes so as you are sort of doing already you can stick that in your CI which would startup this dummy Spring app then make a HTTP request to download the JSON/YAML then shut it down and get the file, as far as I am aware there are no tools that do this at compile time for Java and that's as good as it gets.
The other way is if you do things in opposite where you first design your API interface in swagger and then you generate code (your interfaces) which you then implement yourself.
From the sounds of it you want to be designing your API first, this will allow you to put it in version control and this will make it easier to manage your API versions life cycle and track it's changes, otherwise it can be quite difficult to see how things have changed if you have to search through annotated methods in code, that is what swagger is designed for.
You don't necessarily need to do codegen from your swagger as I have found this to be very awkward at times and it is extremely dumb and generating code, it's just moustache templating and IMO the tool is fundamentally flawed for this reason, but as my most hated saying goes:
it's free so you can't complain
I am working on a rather large API (390+ functions) and I am trying to pull together all the information that the documentation team would need in order to create docs for the project.
I have decided to use JSON Hyperschema to represent this.
I created an annotation processor to look for all of the javax.ws.rs.Path annotation from my code and grab the Javadoc, http method (from annotation) and other parameter information but I am running into a problem.
Hyper schema recommends, and my project spec requires, that the objects sent across an API are to be included as schema in the hyper schema. Typically I would use Jackson to accomplish this. However, as I am in an annotation processor that is not in the main API project, I cannot use class references (ex. User.class where user is an object in my API project and not in my processor) without generating errors. (This is explained here).
My question is, what is the best way around this limitation? I have come up with one way, explained below, but I want this to be pluggable into any other service (of the same format) to document them as well.
As a solution to this, I have thought to break my generator across compile time and runtime. At compile time I would generate JSON hyperschema with placeholders to reference the object schemas. It would also generate a resource file with full names of all of the objects.
At runtime I was planning on generating the schemas for the returned objects then inserting the links to them into the JSON.
IMHO this solution doesn't seem very "elegant". Does anyone have any insight into other ways to accomplish this?
I would recommend following projects:-
jsonschema-hypermedia-support which confirms to enter link description here
OR
Use Spring HATEOAS
Also see
this stackoveflow thread about Restful API
Background:
our web services are company internal, but with a lot different systems using them
we will strive to deprecate/remove old versions of the api as much as we can
There is a lot of information regarding versioning of web services, and our decision was to use the following approach to version our web services:
Keep version in URL (I know some people are against this, but mainly in regards to REST services)
Keep version in namespace.
But, now we are deciding how to actually implement this, and here we have not found that much information of best practices. We use (Java):
Annotations to define our web services (and the web service api)
POJO beans annotated with XML annotations, to define the content
Converter classes to convert from/to the business layer and web service pojo’s
Spring
So, to keep old versions on the web services, we need to keep old versions of the code. To do this, we have basically looked at two different approaches:
1) For each new version, make a complete new copy of the relevant code
This approach would look like this:
com.company.webservice.v3. -all of the web service classes, POJO’s and converters go here
com.company.webservice.v4. -all of the web service classes, POJO’s and converters go here
So, here we have the code duplicated. Our thought in short:
Code duplication. Will be several classes with identical code. Perhaps confusing in Eclipse.
Complete isolation, easy to determine what constitute a specific version
Minimized risk to affect functionality of previous versions of the services
2) Use spring to only make a copy of each class that is affected by a change
This approach means that use Spring IoC and let all versions of the web services use, as much as possible, the same code. Only when we make a change that affect behavior/api, we make new versions of those classes. For example:
com.company.webservice.beans.MyXMLAnnotatedPOJOv3.java
com.company.webservice.beans.MyXMLAnnotatedPOJOv4.java
com.company.webservice.translators.MyXTranslatorv1.java
com.company.webservice.translators.MyXTranslatorv2.java
Could be difficult to clearly see what constitutes a specific version of a web service. Maybe easier to by misstake affect previous versions of the web services when maintaining the code
No code duplication. Only changes are implemented as new classes
Neither approach feels optimal, but we haven’t found much information regarding this.
So, my questions is:
which of the two approaches would you use? Or would you take a completely different approach?
When generating wsdls from Java, I would use the package solution:
com.company.webservice.v3.
It has the code duplication problem, but the POJOs and converters have differences between versions anymay, so code reuse might not be very feasible after all. The main advantage is that if you want to get rid of an old version, you just delete the relevant packages.
I would keep versionnumber in URL, since you are not doing REST anyway. Furthermore, you could check in access logs, if certain versions are still used.
so here is my problem.
I'm using wsdl2java tool, to transform my web services into Java API.
The thing is, when I generate java stubs, my code contains something like that:
public void function(com.xxxxx.ssssss.Myclass myclass){...}
My question is:
how to remove this part "com.xxxxx.sssss." from the whole code, and put it in import section, and all that, not manually, because it would be too long.
Thank you
The vast majority of those classes shouldn't ever be edited at all; just generate them from the WSDL and leave them well alone. Yes, they'll be verbose but you'll just have to live with that (or offer to work on a better code generator for the CXF project, of course!)
The one class that you can edit is the skeleton (…Impl.java) that is generated with the -impl option. In fact, that's the source file that you should edit as it will contain the implementation logic for the service, which is your job. You generate it once and can change it however you want thereafter provided you implement the correct interface and have the right annotations. In particular, using refactoring tools to generate import declarations is perfectly fine (I find that this is easy to do in Eclipse; I'd be startled if other Java IDEs didn't also support something similar).
The only real fly in the ointment comes if you start altering the original WSDL significantly. While adding and removing methods is not too hard to deal with, the bigger the change the more work it is to support. You may have to look carefully at whether the service skeleton should be regenerated from scratch, but that will cost you all your changes; if you're expecting to be doing that a lot, it's a good idea to factor out much of the actual implementation of the service into worker classes so that you only need to rebuild the actual connection to the SOAP service. (Luckily, using Spring DI makes this sort of factorization really easy to manage, so much so that it's a good idea to use it anyway.)
I am starting on a new project with commercial vendor. I need to write an integration module in our application to consume commercial vendor's web service. So, WSDL is not controlled by us.
I think the general approach is to do a "Contract First" development and generate stubs from the WSDL file. I would like to know what technologies are available to do this? I would really like the simplest approach that works. We use Maven 3.0.3 and Spring 3.0.5 extensively. Can I use Spring WebServiceTemplate?
Please let me know if the question isn't clear or additional details are needed.
Thanks,
Tapasvi
You can generate the java stubs with the maven plugin for JAX-WS. Then you can use the stubs in spring to expose them as a webservice. Luckily, it's quite simple :).
Just a suggestion, don't re-generate the stubs every time you build the project, as (obviously) you won't be able to add any code to the stubs, which is sometimes very useful. I made this mistake long time ago and it was quite painful, because I had to put code in places where it didn't belong. In the last few years I used a maven profile to generate the stubs on demand and then I merged them "manually" to add the extra code. Of course, this is only viable if the WSDL doesn't change very often.
I have used axis and the easiest way to do is to run the utility wsdl2java and pass the location of the webservice along with the ?wdsl option.
I know lots of IDE's these days will allow to generate you stubs from within. MyeclipseIDE has an option to ingest an WSDL so does intelliJ. I think the safer approach is to use wsdl. Also if you are using jax-ws you can try
wsimport -keep -verbose location to wsdl
JAX-WS is included in the standard Java 6 distribution making it very simple to use.
Generate stubs with wsimport in the JDK (remember to enable as many warnings as possible, as you want to know anything that may cause problems).