Parsing API data in Kotlin using Jackson

Following my previous article, this post will discuss how to parse API data in Kotlin using the Jackson serialization/deserialization module.

As ever, you can find the code for this post under the following repo.

What is Jackson?

Jackson is a library that helps us to serialise and deserialise data into a format that best suits our needs. Jackson is used extensively in Java applications and now has a fantastic Kotlin-compatible module.

Parsing API Data

A sample of the demo response that we’ll be working with is detailed below:

Sample response data from API

As shown, the results are passed back to us in a JSON format. Let’s get Jackson to deserialise our response body into a malleable JSON blob.

Basic Parse – JsonNode

Firstly we need to import the Jackson module for Kotlin dependency into our build.gradle.kts file:

Importing Jackson module dependency in build.gradle.kts file

Next, we need an instance of the JacksonObjectMapper in our Repository layer. This enables us to use the functions Jackson provides to parse data:

Instantiation of JacksonObjectMapper

Now we can use the objectMapper to read the value of our response body and parse it into a JsonNode. The JsonNode is then passed back to the function that invokes ‘parseResponse()‘:

Parsing a response body into JSON

…which is the ‘makeRequest()’ function:

Accessing nested elements within a JSON object

The above snippet prints an extract from the Json response. Here we’re accessing the first team’s name from within the ‘api’ response.

And that’s it! We now have a response that is parsed into a workable JSON object:

Output from makeRequest function

Our code looks as follows:

Repository code for simple JSON format

That’s great to start with, but it has some drawbacks:

  • We have no control over the data that we’re provided;
  • What if we’re missing some data. For example, if the ‘teams’ node doesn’t return anything? Here the application would throw a null pointer exception when it tries to pick up the 0th element of the array.

To combat these issues, we can convert the JSON object into a Data Transfer Object that we define.

DTO Parse

As above, we’ll import the dependency and instantiate our objectMapper.

Next we need to define our Data Transfer Object. This will try to map the data from the response that we actually care about. We will do this in its own file:

Data Transfer Object

There are a few things in the above snippet that I’d like to point out:

  • At each level we’re defining a new data class to use, giving us control over our data set;
  • Using our own data classes gives us the ability to set nullable values;
  • We’re using the @JsonIgnorePropertiesannotation and set “ignoreUnknown = true”. This tells the objectMapper not to worry if it reads a value that isn’t in the data class – it will just ignore it and move onto the next.

So we have our data classes set up, now we just need to adjust our parsing code to use that type rather than a JsonNode:

Parsing a response body into DTO
Accessing nested elements within a DTO

Here we’ve moved away from the array operator (square brackets) to access various elements. Instead we’re using the attributes within our data classes. A useful side effect of this is the IDE’s code-completion which assists by showing what elements you can have access to when writing your code.

With the DTO classes in place, here is our final code:

Repository code for DTO example

That’s it – we’re now able to call an external API and deserialise the response into a workable format. Next we’ll look to save our results in a database.

Further reading

https://github.com/FasterXML/jackson-module-kotlin

If you enjoyed this type of content and would like to see more, feel free to check out my social media accounts:

Twitter: @sdrobertsCode
LinkedIn
GitHub