Recently, I started learning about API testing in one of the hackathons that my organization keeps organizing for learning purposes. During the hackathon, I came across many new terms — payload, POJO class etc. Today, I’m writing this article about POJOs.
POJO in Java stands for Plain Old Java Object. It is an ordinary object, which is not bound by any special restriction.
In the context of Rest Assured, POJOs are commonly used to represent the structure of JSON or XML payloads in HTTP requests and responses. In layman's language, POJOs are used to create payload data to be sent for API request.
But, why do we need POJO class when we have other ways to send payload data. On doing some research, here are some reasons that I feel make POJO a better candidate than other options:
Readability and Maintainability: POJOs provide a clean and readable way to model the structure of request and response payloads. By representing the data as objects with meaningful field names, the code becomes more self-explanatory and easier to understand for even a new joiner .
Encapsulation of Data: POJOs allow you to encapsulate data and related behavior within a single object. This aligns with the principles of object-oriented programming, making the code more modular and maintainable. Use of private class variables and public getters and setters which will provide you Encapsulation.
Type Safety: When you use POJOs to represent the expected structure of the response, the compiler can catch type mismatches and other errors at compile time. This helps in avoiding runtime errors related to incorrect data types.
Easy Serialization and Deserialization: Rest Assured automatically handles the serialization of Java objects into JSON or XML format when sending requests, and deserialization of responses into Java objects.
I am sure there are many more advantages of using POJOs.
but, When do we use nested POJO
Nested POJOs (Plain Old Java Objects) are needed in situations where your data model has a hierarchical or nested structure, meaning one object contains another object or objects. This can occur in scenarios where your data has a complex structure with relationships between different entities.
Now have a look at the request payload structure below :
This payload structure is not flat, meaning all the fields on same level. Actually this is hierarchical data structure.
As you can see, some fields like "id" and "name" are nested inside the category object. Same logic applies to the fields "id" and "name" under tags object. Here nested POJOs comes into picture.
In order to visualize this, we can make use of jsonpathfinder.com . I can see that paths of category id and tags id are different and the hierarchy is also different. This helped me decide that nested Pojo classes need to be implemented here.
It feels very overwhelming to handle this type of nested JSON Object at a glance. So, we will split this into small parts or objects. So basically, we can split the above JSON into 3 parts – category, tags and petPOJO(main requestPayload). In the above nested POJO classes ,tags object is having an array of objects in it. There is no ready-made data type to represent elements of this array as a whole. So here we need to create a POJO class that can contain all details of these objects.
1.This is how I have created a separate category POJO class which will have values of fields "id" and "name" .
2. TagsPOJO class contains field names "id" and "name". This is how I have created a separate class for the same.
Also, one more interesting thing in the above payload was , status values were a specific set of values that were valid. Here user should be restricted for entering any values and should be provided with certain set of values only. Here, enum comes for our rescue!
An enum is a special "class" that represents a group of constants (unchangeable variables, like final variables).
3. Finally we have all the sets of data that we need to create our request payload. This is my final payload class. Please have a look at the highlighted part- here we are creating objects of CategoryPOJO and TagsPOJO class.
Here , when getter and setter methods of CategoryPojo or TagsPojo are called , they inturn call their respective nested class' getter and setters. This way we can achieve creating nested payloads by creating nested Pojo classes.
Using Plain Old Java Objects (POJOs) in programming has several advantages, but it also comes with certain limitations. Here are some of the limitations of using POJOs:
Boilerplate Code: POJOs often require a lot of boilerplate code for getters, setters, constructors, and other standard methods. This can make the code verbose and harder to maintain. (when I put it in simple words, boilerplate code means the repetitive code but which is unavoidable.)
No Built-in Validation: POJOs do not come with built-in validation mechanisms. Validating the state of a POJO often requires custom code or the use of external validation frameworks.
Tight Coupling: POJOs can lead to tight coupling between classes if not designed carefully. Changes in one part of the system might have unintended consequences on other parts due to the shared use of POJOs.
Limited to Java Language: While the term "POJO" is associated with Java, the concept itself is language-agnostic. However, the term is mostly used in the context of Java programming. This limits the portability of the concept to other programming languages.
Despite these limitations, POJOs remain a widely used and effective programming approach, especially in scenarios where simplicity, readability, and interoperability are crucial.
In my opinion, use of POJOs should depend on the specific requirements of the application and the development environment should guide the choice of whether to use POJOs or other design patterns.
Hope my experience that I have shared with you was insightful !