Top

Deserializing API Responses Into Java Records

Deserializing API Responses Into Java Records

Here is a recipe for deserializing API responses into the new Java construct: Record, and using it for easier verification.

NOTE: At the time of this writing, Record is a preview featuring, meaning it’s not officially a permanent feature of Java yet. It’s been introduced in Java 14 to allow developers to provide feedback on its implementation. So, implementation can change or the feature can be totally removed. I say all of that to say, don’t use this in your production code just yet.

 

 

Recipe to Deserialize API Responses Into Java Records

Ingredients

  • Rest-Assured (or any other library for making requests: e.g. HTTPClient)
  • Jackson binding
  • Java 14+ (for Records)

Instructions

  1. Create Records for each expected object in the response body
  2. Create instance of Record to serialize expected response
  3. After making an API request, deserialize response into the Record representing the top-level object in the body
  4. Compare created instance with deserialized object
— Angie Jones

 

Live Stream Video

 

 

Ingredients

 

1 Rest-Assured

 

My favorite library to make API requests is Rest-Assured. To use it in our code, we need to add it as a dependency. I’m using Maven so I add it to my pom.xml file.

 

 

 

2 Jackson Binding

 

The Jackson binding library assists with deserializing API responses and mapping certain fields (like ones with spaces or a different name) to our Java fields. I add this to the pom.xml as well.

 

 

 

3 Java 14+

 

Records were released as a preview feature as part of Java 14. So you’ll need at least this version of Java to use the feature. IntelliJ allows us to enable preview features. So, be sure to set this up appropriately.

 

 

Instructions

 

1 Create Records to serialize expected response

 

The API we’re going to be using is Zippopotamus which given a zip code, it returns information about the location.

Request

 

Response

 

Based on this response, we create a Record to model it.

Notice with Records, we only need to specify the fields. We do not need to explicitly define getter and setter methods, nor override the inherited equals(), hashCode(), or toString() methods. We get this for free! 🎉 (watch out Lombok)

 

NOTE: When using POJO classes for deserialization, we only need to use the @JsonProperty binding for response fields that differ from the Java variable names, however, since Records are brand new and not yet permanent, we need to use @JsonProperty to bind every field of the response. Once Records become permanent, I believe this will be properly supported by the Jackson project.

 

2 Create instance of Record representing expected response

 

In a separate class, I created a test. Within the test method, I created an instance of a Record to represent the response that I’m expecting from my call.

 

3 Deserialize response into the Record

 

Next, I make the API request using Rest-Assured and then call the as() method, which deserializes the response body into a Java object. I pass in the Record which represents the top level object of the response.

By printing out expectedLocation, I can see that the Location record was properly populated!

 

4 Compare expected result with actual result

And since the equals() method of our Location record is already taken care of by default, asserting against it is a breeze!

 

Full Test Code

 

 

See Code on Github

Angie Jones
5 Comments
  • Cay Horstmann

    Very nice. I’d rename Places as Place since each instance describes a single place.

    May 7, 2020 at 9:48 pm Reply
    • Angie Jones

      In the video, I originally named it place and the deserialization didn’t work because it didn’t map to places in the response. Technically, it can work now because I used @JsonProperty anyway but when Jackson supports records, I’ll take those annotations out and it’ll need to match the field name in the response.

      May 8, 2020 at 7:55 am Reply
  • Tom

    Interesting. I’ve always used Lombok for setters/getters etc but never liked it.

    This should enable me to remove it in most cases. Fingers crossed it comes out of preview.
    May 10, 2020 at 4:43 am Reply
  • Preeti

    HI,

    Let say i have expected Json which i converted into class object and i have converted actual Json (fetch from API) and then convert to class object.
    How i can compare two class object and return mismatch data.
    May 21, 2020 at 5:41 am Reply
  • Alex

    Hi,

    I always think that expected value is a known value (prepared), while the actual value is the result of some action.
    Am i right? What do you think, Angie?
    July 8, 2020 at 9:41 pm Reply

Post a Reply to Alex Cancel Reply