Let’s say you want to connect your web/application with a third party REST API. Within this article I’ll put as example the SonarQube API, given that is the one I’ve used in my last personal project (see post).
In this post I’ll describe how I solved the situation of having no schema for the data that you’re retrieving from the REST API. How can we map this structure to Java Objects?
A sample REST API: SonarQube
As mentioned in the previous post SonarQube is a open source platform to manage code quality. They have a running project called Nemo: http://nemo.sonarqube.org.
The SonarQube team provides a really good documentation of their API that you can find directly at their Nemo project, in the footer: Web Services API.
Both XML and JSON formats are accepted for this API. You can play a little bit with it by executing, for XML and JSON responses respectively:
curl -H "Accept: application/xml" http://nemo.sonarqube.org/api/projects
curl -H "Accept: application/json" http://nemo.sonarqube.org/api/projects
Ok great, let’s focus on the JSON part (anyway you could face the same situation using XML). What should we do in our application with such a beautiful JSON?
"nm": "AS3 Core Lib",
"k": "org.apache.activemq: activemq-parent",
Well, we could use the Jackson library and any of the available methods to parse this document:
- Streaming API
- Tree Model
- Data Binding (Simple or Complex)
As stated in the Jackson in Five minutes page usually Complex Data Binding is the most natural way of working with JSON data. In our case imagine that you want to build a table with several properties of the projects in SonarQube and you want to play a little bit with this model (sort, aggregate, etc.). We will go for POJOfying.
Looking for solutions
What would you do next in order to build the POJOs in Java? If you are not a google-person maybe you code the POJO yourself, actually it’s not so bad, a class with four fields. Piece of cake. Prepare a coffee when you work with the response given by this API when you ask for issues (violations).
In my case, I tried to look for a “POJO Library” provided by SonarQube. Never found it. There is something in their documentation that is actually deprecated: the Web Service Java Client. Actually, this library is more ambitious, not only modelling the data but also providing the interface to access to the different services. At the end, I have come to the conclusion that it’s not a common practice to provide the POJOs if you are offering, for example, a REST interface. It makes sense: are you going to provide POJOs for every programming language?
Then I tried to find the schema, in my opinion, that would be perfect. It’s describing the data in a generic way and you could think of using it to generate the POJOs. Just like JAXB can generate POJOs given an XSD file. Again in my experience is not common that the platforms offer this (looked for JIRA REST API schema, not found).
The only [valid] solution I have found
Well, in order to take a good example to play with this solution let’s retrieve the issues from Nemo (limiting the page size to 10). My recommendation is that you save the response in a text file.
curl -H "Accept: application/json" http://nemo.sonarqube.org/api/issues/search?ps=10 > issues.json
And the magic comes now. Go to one of the online POJO generators available on the Internet. My favorite is www.jsonschema2pojo.org. Even though the site name could make you think that you need a schema actually you don’t. It infers the data model from the document.
You can either preview the classes that are going to be generated or you can download them directly and include this jar into your project. Ready to go!
If you don’t like the automagically generated POJOs you can always edit them and fine-tune the different fields. It’s a very easy way to be able to do Complex Data Binding with JSON but it still has some cons:
- You may need to do different queries to different services if you want a complete POJO set.
- Some data types can’t be inferred.
- The dataset you need for feeding the generator has to be significant. If there are some fields missing for the JSON you’re using they are not going to be generated in the POJOs, but later they will appear as additional properties.
What about you? Have you found anything better?