12

Recently I have stumbled upon a situation where my new team is heavily using JsonObject for doing rest data interchange. Their view is while using pojo we are binding tightly with the rest service, while jsonObject gives freedom. Also it saves from unnecessary data serialisation at the same time reducing number of classes heavily.

I have some points to encounter them as:

  1. Pojo gives more meaning to data and we are holding data with correct data type.
  2. If we need only 2 fields of 10 fields of json, we can deserialize to 2 fields class with @JsonIgnore

I don't know exactly on the cost of deserialisation, but somehow I have a feeling it shouldn't be much difference.

Can someone help me understand which perspective is way to go ?

Please provide some pros and cons of using POJO and JSONObject.

Thanks

Richard
  • 25,390
  • 3
  • 25
  • 38
rohit
  • 862
  • 12
  • 26

6 Answers6

14

I see the following advantages in having pojos

  1. Readability - You will not really know the structure of a complex json. writing a simple get will require one to know the structure of the json. Please refer to the "POJOs over JSON Objects" section of my article here -> https://medium.com/tech-tablet/programming-went-wrong-oops-38d83058885

  2. Offers Type Checks - We could easily assign a Cat to a Dog and not even know about it till runtime.

  3. Feels more object-oriented with Composition & encapsulation - It's easy to understand the designer's perspective with a POJO. A Car which IS-A Vehicle that HAS-A Wheel.

  4. You could choose what you wanna deserialize and keep only that in memory - When deserializing the object that we have just received over the network, with a JSON Object, there is no way to choose what has to be deserialized and stored into memory. If you have an object of 1 MB size where only 200 Bytes is your payload, we will end up holding the entire 1 MB object in memory if we don't use POJOs.

  5. Allows collection to be used and stream operations on them in a legible way - There is no native support for stream operations in a JsonNode. We will need to use a StreamStupport object which could be avoided.

  6. Allows cross framework referencing. With a few annotations, you can choose to map specific fields to a database client - When you use an ORM framework for you database, it's easy to annotate and map entities to the database schema.

  7. Naturally supports design patterns

  8. Minimalizing non-native dependencies - Why do you have to use a JsonNode or equivalent that does not come by itself in native Java? Especially if it has the above disadvantages.

If you are concerned about the rituals that come with a pojo like having getters, setters etc, take a look at "Lombok". This library will help you create your pojos in a concise way and still reap the above benefits.

On the other hand if you are are dealing with a hard to change API that responds with a dynamically changing response, JsonNode is a quick win candidate.

Prasanna
  • 2,593
  • 7
  • 39
  • 53
8

It really depends on the situation and the nature of your application. If the data your are receiving has no fixed structure/field names/data types or it is ever changing then of course using JsonObject makes more sense.

On the other hand, if it is of fixed structure and involves operations which access the fields, its better to go with pojo. It has better readability IMO.

Rishikesh Dhokare
  • 3,559
  • 23
  • 34
5

Depends on circumstances:

  • Use Pojo :

    1. If the data fields are fixed like their name, type use Pojos, as it will be clear and easily readable.
    2. Refactoring will be easier if it is used in many places.
    3. If you want to persist this data in db then modification of data will also be easy. Suppose there is a data in your pojo which is used while performing calculation, but you don't want save it in db ( so you can simply do it by using @Transient keyword in java, but if you have used JsonObject this would have required some code changes).
    4. Suppose you don't want to pass null values in the response, you can easily do it using pojos by using @JsonInclude(Include.NON_EMPTY) in java.
  • Use JsonObject:

    1. If data fields are not fixed like their type or structure, so you won't be able to map it in pojo.
Bishal Jaiswal
  • 1,684
  • 13
  • 15
2

I want to add:

  • with POJOs you can use the builder pattern.

  • future refactors will be more easy. Imagine you have a class Person, and you use this class in many places in your code. If your Person class needs to change one of its fields, then you can find easily where to change it.

  • using POJOs makes your code more cohesive with your domain. If you are writing code for a car company, you will have classes like Car, Wheels, Engine, etc. Your code will become more readable and testable.

Perimosh
  • 2,304
  • 3
  • 20
  • 38
2

This argument really boils down to whether you want to use POJOs or Maps for the data you are dealing with, as that is the fundamental difference between the 2 styles of handling data.

JsonObject (from jee7) is just a Map (the actual type signature extends Map<String, JsonValue>).

Using POJO's (eg deserialised using Jackson) are real objects.

So if you dont use domain/model classes for your data normally then I guess a Map will do. If you do (like most developers would), then it's a good idea to extend this practice to your API contracts.

To address specific points:

JsonObject saves from unnecessary data serialisation at the same time reducing number of classes heavily.

It doesn't, both of these JSON API's require serialisation/deserialisation, which is the process of turning wire data into an object. I would bet that Jackson is faster than JsonObject, however as Satyendra Kumar pointed out benchmarking is going to prove it one way or other.

while using pojo we are binding tightly with the rest service, while jsonObject gives freedom

If you are using the data from the API you are bound to the data model, whether you get the data from a property foo by response.getFoo() or response.get("foo").

For a really comprehensive discussion on the tradeoffs between classes and maps, check out this SoftwareEngineering post

It's worth pointing out that using Jackson/POJOs doesn't mean you are tightly coupled to your local model of a REST response. Jackson has excellent support for the Tolerant Reader pattern, which means that new fields in the API response will not break deserialisation, and a bunch of annotations like @JsonCreator, @JsonValue, @JsonIgnore for mapping the API responses back to your local domain model.

It also provides powerful tools for dealing with collections and generics.

Finally if the service you are interacting with is big and complex, if they provide a swagger/raml spec then you can generate the models based on that spec which should greatly reduce the time taken to curate the POJOs.

stringy05
  • 6,511
  • 32
  • 38
1

Their view is while using pojo we are binding tightly with the rest service, while jsonObject gives freedom.

Ask them for how long this freedom is required? Is the API model going to change always? It WILL settle down at some point. Also, how is it binding tightly? If there is some part of the model that you are not sure of, you can create a generic object for that part, that will give you as much flexibility as you want.

Also it saves from unnecessary data serialisation at the same time reducing number of classes heavily.

I don't think it is unnecessary. Using JsonObject directly is simply cumbersome. About reducing the number of classes, you should anyway have some model class for data that is being exchanged. It gives more clarity. If you are using Swagger, it will add to the specification of your REST endpoints. Swagger automatically creates forms to enter data based on the data model. API becomes easier to maintain (no extra documentation required). Testing becomes easier.

I don't know exactly on the cost of deserialisation, but somehow I have a feeling it shouldn't be much difference.

The only way to be sure is benchmarking. You can use this as a starting point to get an insight and compare the current implementation https://github.com/fabienrenaud/java-json-benchmark.

Satyendra Kumar
  • 357
  • 2
  • 13