REST Assured POJO and Serialization & Deserialization

Hand-written JSON strings are fine for one test and painful for a hundred. POJOs let you build request bodies and read responses as normal Java objects, while REST Assured converts between Java and JSON for you. This guide covers POJOs, serialization and deserialization, nested objects and lists, the Jackson annotations you'll actually need, and the errors you'll run into.

Advertisement

What Is a POJO?

A POJO (Plain Old Java Object) is a simple class with private fields, getters and setters, and a no-argument constructor — no framework base class required. In API testing, a POJO models a request or response body:

public class User {
    private String name;
    private String email;
    private int age;

    public User() {} // needed for deserialization

    public User(String name, String email, int age) {
        this.name = name;
        this.email = email;
        this.age = age;
    }

    public String getName()  { return name; }
    public String getEmail() { return email; }
    public int getAge()      { return age; }

    public void setName(String name)   { this.name = name; }
    public void setEmail(String email) { this.email = email; }
    public void setAge(int age)        { this.age = age; }
}

Interview answer:

"A POJO is a plain Java class with private fields, getters, setters and a default constructor. In REST Assured I use POJOs as request payloads and to map JSON responses to Java objects, which makes tests type-safe and easier to maintain than raw JSON strings."

Why Use POJOs?

Manual JSON strings POJOs
Typos and missing quotes break requests The compiler catches mistakes
Hard to change one field per test Set one field with a setter or builder
Painful for large or nested payloads Nested objects and lists are natural
Values read with JSON paths as strings Values read with typed getters
Little reuse Shared models across many tests

Serialization: Java Object → JSON

Serialization converts a Java object into JSON for the request body. REST Assured does it automatically when you pass an object to body() and a JSON library such as Jackson or Gson is on the classpath:

User user = new User("John", "john@test.com", 28);

given()
    .contentType(ContentType.JSON)
    .body(user) // serialized to JSON automatically
.when()
    .post("/users")
.then()
    .statusCode(201);

The request body sent:

{
  "name": "John",
  "email": "john@test.com",
  "age": 28
}

If you need the JSON string itself — for logging or a file — serialize manually:

String json = new ObjectMapper().writeValueAsString(user); // Jackson
String json2 = new Gson().toJson(user);                    // Gson

Deserialization: JSON → Java Object

Deserialization converts a JSON response into a Java object, so you read values through getters instead of JSON paths:

User user = given()
    .when()
    .get("/users/101")
    .then()
    .statusCode(200)
    .extract()
    .as(User.class);

Assert.assertEquals(user.getName(), "John");
Assert.assertTrue(user.getEmail().endsWith("@test.com"));

Manual equivalents:

new ObjectMapper().readValue(body, User.class);

or:

new Gson().fromJson(body, User.class);
  Serialization Deserialization
Direction Java object → JSON JSON → Java object
Used for Request payloads Response handling
REST Assured .body(user) .extract().as(User.class)

Nested Objects and Lists

Real payloads are nested. Model each JSON object as its own class:

{
  "orderId": 5001,
  "customer": {
    "name": "Asha",
    "city": "Pune"
  },
  "items": [
    {
      "sku": "BOOK-1",
      "qty": 2
    },
    {
      "sku": "PEN-7",
      "qty": 5
    }
  ]
}

The corresponding Java models can look like this:

public class Order {
    private int orderId;
    private Customer customer;
    private List<Item> items;

    // getters, setters, no-arg constructor
}

public class Customer {
    private String name;
    private String city;

    // getters, setters, no-arg constructor
}

public class Item {
    private String sku;
    private int qty;

    // getters, setters, no-arg constructor
}

Deserialize the response:

Order order = when()
    .get("/orders/5001")
    .then()
    .extract()
    .as(Order.class);

Assert.assertEquals(order.getItems().size(), 2);
Assert.assertEquals(order.getCustomer().getCity(), "Pune");

When the Response Is a JSON Array

User[] users = when()
    .get("/users")
    .then()
    .extract()
    .as(User[].class);

Or for a list nested inside the response, such as { "data": [...] }:

List<User> list = when()
    .get("/users")
    .then()
    .extract()
    .jsonPath()
    .getList("data", User.class);

Jackson Annotations You'll Actually Use

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {

    @JsonProperty("first_name")
    private String firstName;

    // ...
}
  • @JsonIgnoreProperties(ignoreUnknown = true) — with Jackson's default settings, a response field that has no matching POJO field can make deserialization fail. This annotation (or a configured ObjectMapper) keeps tests stable when the API adds fields.
  • @JsonProperty — maps snake_case or otherwise different JSON keys to Java names.
  • @JsonInclude(NON_NULL) — builds partial payloads, for example for PATCH requests or negative tests with missing fields.

Less boilerplate: many teams generate getters, setters and builders with Lombok (@Data, @Builder, @NoArgsConstructor), or use Java records for read-only response models with recent Jackson versions.

Common Errors and Fixes

Error Cause Fix
"Cannot serialize object because no JSON serializer found in classpath" No Jackson or Gson dependency Add jackson-databind (or Gson) to pom.xml
UnrecognizedPropertyException Response has a field the POJO doesn't @JsonIgnoreProperties(ignoreUnknown = true)
"No suitable constructor" / cannot construct instance No no-argument constructor Add a public no-arg constructor
Fields missing from the request JSON No getters (Jackson serializes through getters) Add getters, or annotate the fields
Wrong key names in the JSON Java naming differs from the API's @JsonProperty("api_name")

Jackson vs Gson

  Jackson Gson
Maintained by FasterXML Google
REST Assured support Yes — preferred when both are present Yes
Annotations and configuration Extensive (@JsonProperty, @JsonIgnoreProperties, @JsonInclude…) Simpler (@SerializedName, @Expose)
Typical choice Most Java API frameworks Simple projects, Android

Best Practices

  • Use one POJO per request or response model, preferably in a models package.
  • Keep field names aligned with the API contract; use @JsonProperty where they differ.
  • Ignore unknown properties in response models so new API fields don't break tests.
  • Use builders or factory methods for test data so each test changes only what it needs.
  • Combine POJO assertions with JSON Schema Validation for contract checks.

See how requests are built and responses extracted step by step in the REST Assured Visualizer.

From Real Projects

My API experience covers CRUD operations, HTTP methods, JSON path, and validating JSON and XML responses, and my automation work was in Java with TestNG. That combination is exactly what REST Assured builds on: HTTP calls in Java, JSON path for extracting values, and TestNG for running and grouping the tests. If you already know Selenium with TestNG, REST Assured fits into the same project structure. Testsigma supports web, mobile and API test automation, so understanding APIs was part of understanding the product I was testing. POJOs make request bodies readable and reusable across tests. See also: Response Validation in REST Assured.

📚 Official documentation: REST Assured official site · MDN: HTTP

FAQs

What is a POJO class?

A Plain Old Java Object — a simple class with private fields, getters, setters and a no-argument constructor, used here to model request and response bodies.

What is serialization in REST Assured?

Serialization means converting a Java object to JSON for the request body. REST Assured does it automatically when you pass an object to .body() with a JSON content type and Jackson or Gson on the classpath.

What is deserialization?

Deserialization means converting a JSON response into a Java object, typically with .extract().as(User.class).

How do you deserialize a JSON array?

Use .extract().as(User[].class) for a top-level array, or jsonPath().getList("data", User.class) for a list inside the response.

Why does deserialization fail with "Unrecognized field"?

The response contains a field your POJO doesn't have. Add @JsonIgnoreProperties(ignoreUnknown = true) or configure the ObjectMapper to ignore unknown properties.

Jackson or Gson?

Jackson is the common choice for Java API frameworks because of its annotations and configuration; Gson is simpler. REST Assured supports both.