Java Micro Service API Generation
TL;DR - How to get java Vert.x to automatically generate a Open API v3 spec (a.k.a. Swagger) and serve it to Swagger UI, through Vert.x. Why I wanted to do it, and what benefits we saw.
Motivation
I joined a new role earlier this year as a Full Stack developer.
My colleagues had created RAML files for unit testing.
These files were also used to help document end points.
Unfortunately, the files were out of date;
- Developers found it a chore to keep the RAML files up to date.
- Testers would have to ask developers for example payloads for API requests.
- Automation engineers would ask developers for change details when automation failed.
- Nobody knew how many end points we had.
- Nobody wanted to write documentation for immature end points.
It was a real mess and something had to change!
I wanted to set up API documentation on the JAVA micro services in such a way that it would NOT be a burden on developers to keep up to date. I also wanted everyone a single source of truth.
Longer term, what I really wanted was to create SaaS ready API documentation…
Research and Development
I knew about swagger from previous projects; more importantly, Swagger UI.
My vision was to get Swagger UI into every micro service we had.
I searched the internet for ways to get a framework named Vert.x to generate Swagger.json. I found lots of JAVA related projects but only one specific to my requirements. It was good, but missing lots of implementation. The author had made a fantastic start to the project and wrote up omissions in the README.
Several weeks later…
vertx-auto-swagger was born.
A sample repository that would;
- Take JAVA annotations and generate OpenAPI 3.0 specification JSON.
- Serve the specifcation out on an end point.
- Serve Swagger UI out as a website.
- Use Swagger UI as a replacement to Postman.
Point 1 – I updated the implementation to include Schema definition and Examples of payloads.
Point 2 – I served the swagger specification out on /swagger.
Point 3 – I had a choice of either hosting a Swagger UI away from the code base or include Swagger UI within the codebase. I went with the latter as I did not want to battle with any CORS issues and wanted to reduce any DevOps overhead.
I took a distribution copy of Swagger UI and served it out through Vert.x as a static website.
Point 4 – I wanted to take advantage of the “Try it out” button in Swagger UI that would auto populate payloads with an example JSON. This was the end deliverable, as to give users a better alternative to using dekstop based applications such as Postman.
I wanted our swagger to have examples of request payloads so that a user could click and run examples. If the API changed then a developer could reflect the changes immediately for others to see.
The sample project uses no database calls, and mocks example requests.
The sample project uses Schema definitions with required field support.
This was a big must for us as I wanted to eventually have one routing method to validate all requests to a schema definition. The sample project has examples of this; if you try to send in an item that does not exist in the schema definition then a 400 is thrown to tell the user that a bad request was performed, with details on which item in the request was rejected.
Challenges
Path parameters!
Swagger UI has a “try it out” button. – It’s great, but it takes any Path parameters entered and substitutes them out using curly braces in the routing.
This is totally fine if one can rely on routing to use braces, but in my scenario, Vert.x insisted on using colon : to express parameters in the path.
I managed to get a fix in place for this, and sent a Pull Request in to Swagger API to get it adopted.
https://github.com/swagger-api/swagger-js/pull/1338
Unfortunately it was rejected as the Swagger spec does not support colon’s.
Hi @anupsaund!
We’re unable to add support for this, since it’s not part of the Swagger/OpenAPI Specification.
If you’d like support for colon notation in parameters, the first step is to start a discussion on the OpenAPI Specification repository: https://github.com/OAI/OpenAPI-Specification/issues/new.
If it’s added to a future version of the specification, we can then add support for it here ?
Also note that you could (and for now, should) modify the output of your generator to translate colon path parameters to the templating format that OpenAPI calls for today.
I’m going to close this out since it’s not possible to accept such a change at this time. Thanks for your efforts!
I then took to hacking the code into my minified version of Swagger UI. It’s not ideal but at the moment, it works. BTW, it was too hard to switch colons to braces in Vert.x.
I also created a ticket over at OpenAPI for colon support to be considered for inclusion into the specification. https://github.com/OAI/OpenAPI-Specification/issues/1681
Did it actually work for us?
It took a few months of development work but we now have a fully documented customer facing API with JWT authentication that is being used cross functionally.
We also went ahead and moved the generator code into a common library so that it can be used across micro services.
We all suspected that the API’s we had written would require attention in areas with respects to correct response codes and 500 errors. We now have full visibility of what needs doing and surprisingly, the mountain of tech debt we suspected turned out to be a few mole hills of work! We now have visibility of what we need to incorporated into out sprint planning, in order to make our API’s robust and eventually customer facing.
Summary & Repo Link
I hope this article inspires others to create a similar holistic solution to API documentation and web API contracts. It was very well received by my colleagues and senior management as a MUST feature for us to incorporate into everything we do.
The repository link is below. Please check it out, there is a more comprehensive read me in there from a technical perspective.
Github Project: https://github.com/anupsaund/vertx-auto-swagger