Advanced REST Assured Concepts

Last Updated : 28 Jan, 2026

When testing web services, especially APIs, having a robust testing framework is essential. REST Assured is a popular Java-based library that simplifies API testing for developers. It allows for smooth integration with various testing tools and frameworks, making it a go-to solution for developers and testers working on API testing.

It covers advanced REST Assured concepts such as authentication mechanisms, schema validation, XML handling, and automation of complex API workflows. These topics are essential for anyone aiming to deepen their understanding of REST Assured and effectively automate testing for real-world APIs.

Understanding Authentication Mechanisms

When testing APIs, authentication is often a critical part of interacting with secured endpoints. REST Assured simplifies working with various authentication strategies, including basic authentication, token-based authentication, OAuth 2.0, and custom headers/cookies.

Basic Authentication

Basic Authentication is one of the simplest forms of authentication, requiring a username and password to access the API. In REST Assured, it can be handled easily with the auth().basic() method.

  • Open Postman and go to your collection.
  • Click the three dots (...) next to the collection name and select Edit.
  • Navigate to the Authorization tab in the collection settings.
  • Choose the Type of authorization from the dropdown. Common options include:
Screenshot-2025-01-25-165957


Example:

Java
package io.learn.auth;

import org.testng.annotations.Test;

import static io.restassured.RestAssured.given;

public class BasicAuthTest {

    @Test
    public void testBasicAuth() {
        given()
                .auth()
                .basic("postman", "password")
                .baseUri("https://postman-echo.com")
        .when()
                .get("/basic-auth")
        .then()
                .statusCode(200);
    }

    @Test
    public void testBasicAuthNegative() {
        given()
                .baseUri("https://postman-echo.com")
        .when()
                .get("/basic-auth")
        .then()
                .statusCode(401);
    }
}

Output:

Basic Auth Output
Basic Auth Output

This sends a request with the specified credentials and verifies the response status code.

Token-Based Authentication

Many modern APIs use token-based authentication, where a bearer token is included in the request header. This method is commonly used with APIs like those from third-party services.

Example:

Java
package io.learn.auth;

import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.equalTo;

public class FootballAPITests {

    @BeforeClass
    public void setUp() {
        RestAssured.baseURI = "https://api.football-data.org";
        RestAssured.basePath = "/v4";

        RestAssured.requestSpecification = new RequestSpecBuilder()
                .setContentType("application/json")
                .addHeader("X-Auth-Token", "XXXXXXXXXXXXXXXX") // use your API Key
                .build();
    }

    @Test
    public void testCase1() {
        get("/teams")
                .then().statusCode(200);
    }

    @Test
    public void testCase2() {
        get("/teams/66")
                .then().statusCode(200)
                .body("name", equalTo("Manchester United FC"));
    }
}

Output:

Tokenbased Authentication
Tokenbased Authentication
Screenshot-2025-01-27-112818
Output

Here, the Authorization header includes the bearer token, which authenticates the user for accessing protected endpoints.

OAuth 2.0 Authentication

OAuth 2.0 is an advanced and secure authentication mechanism that is widely used by services like GitHub and Google. It requires an access token that is passed using the auth().oauth2() method in REST Assured.

Example:

given()
.auth().oauth2("<token>")
.when()
.get("/user/repos")
.then()
.statusCode(200);
Java
package io.learn.auth;

import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.testng.annotations.Test;

import static io.restassured.RestAssured.given;

public class GitHubAPITests {

    private RequestSpecification requestSpecification = new RequestSpecBuilder()
            .setBaseUri("https://api.github.com")
            .setContentType("application/json")
            .build();

    @Test
    public void testCase1() {
        given().
                spec(requestSpecification)
        .when()
                .get("/users/rakesh-vardan/repos")
        .then()
                .statusCode(200);
    }

    @Test
    public void testCompleteFlow() {

        String userName = "rakesh-vardan";
        String repoName = "my-dummy-repo-test";
        String payLoad = "{\"name\":\""+repoName+"\",\"description\":\"This is a new repository\",\"homepage\":\"https://github.com\",\"private\":false,\"is_template\":false}";
        String oAuth2Token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // use your access token

        // create a new repo
        given().
                spec(requestSpecification)
                .body(payLoad)
                .auth()
                .oauth2(oAuth2Token)
                .log().all()
        .when()
                .post("/user/repos")
        .then()
                .statusCode(201)
                        .log().all();

        // delete that repo
        given().
                spec(requestSpecification)
                .auth()
                .oauth2(oAuth2Token)
                .log().all()
        .when()
                .delete("/repos/"+userName+"/" + repoName)
        .then()
                .statusCode(204)
                .log().all();
    }
}

Output:

Screenshot-2025-01-27-114444
GitHub authentication

This method ensures secure access by handling OAuth 2.0 tokens dynamically in git-hub it will create a dynamic repo using the Token bases authentication.

Custom Headers and Cookies

For custom authentication, REST Assured allows developers to inject custom headers and cookies dynamically.

Example:

given()
.header("Custom-Header", "value")
.cookie("SessionID", "12345")
.when()
.get("/endpoint")
.then()
.statusCode(200);

In this example, custom headers and cookies are passed along with the request to simulate user authentication.

2. Schema Validation

Validating the response schema ensures that the API's output follows a predefined structure. This is especially important for APIs that deal with complex data structures or are expected to return consistent formats across different requests.

JSON Schema Validation

REST Assured integrates with the JSON Schema Validator library to perform schema validation. By defining the expected structure of the response (usually in a .json file), you can ensure the response matches the required format.

Steps for Schema Validation:

  1. Define the Expected Schema
    Example schema for a pet API:
Java
package schemavalidation;

import static io.restassured.RestAssured.get;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;

import java.util.HashMap;
import java.util.Map;

import org.hamcrest.Matcher;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;

public class SchemaValidationTests {

    @BeforeClass
    public void setUp() {
        RestAssured.baseURI = "https://petstore.swagger.io";
        RestAssured.basePath = "/v2";

        RestAssured.requestSpecification = new RequestSpecBuilder()
                .setContentType("application/json").build();
    }

    @Test
    public void testSchemaForPet() {
        Map<String, Object> petData = getPetData();

        // create a new pet - POST
        String newPetID = given().body(petData).when().post("/pet").path("id").toString();
        System.out.println("New Pet created is: " + newPetID);

        // verify the new pet - GET
        get("/pet/" + newPetID).then().statusCode(200)
                .body("status", equalTo("pending"))
                .body(matchesJsonSchemaInClasspath("PetSchema.json"));
    }

    private Matcher<?> matchesJsonSchemaInClasspath(String string) {
		// TODO Auto-generated method stub
		return null;
	}

	private Map<String, Object> getPetData() {
        Map<String, Object> categoryMap = new HashMap<>();
        categoryMap.put("id", 1);
        categoryMap.put("name", "dog");

        Map<String, Object> petMap = new HashMap<>();
        petMap.put("name", "doggie");
        petMap.put("status", "pending");
        petMap.put("category", categoryMap);
        return petMap;
    }
}

PetSchema.json

json
{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "$ref": "#/definitions/Welcome5",
  "definitions": {
    "Welcome5": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "integer"
        },
        "category": {
          "$ref": "#/definitions/Category"
        },
        "name": {
          "type": "string"
        },
        "photoUrls": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "tags": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Category"
          }
        },
        "status": {
          "type": "string"
        }
      },
      "required": [
        "category",
        "id",
        "name",
        "photoUrls",
        "status",
        "tags"
      ],
      "title": "Welcome5"
    },
    "Category": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        }
      },
      "required": [
        "id",
        "name"
      ],
      "title": "Category"
    }
  }
}

Output:

PetSchema.json extracted output
PetSchema.json extracted output

Add the Dependency
Add the JSON Schema Validator dependency in your pom.xml:

<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>5.3.0</version>
</dependency>

Validate the Schema
Example validation code:

given()
.baseUri("https://petstore.swagger.io/")
.when()
.get("/pet/1")
.then()
.assertThat()
.body(matchesJsonSchemaInClasspath("pet-schema.json"));
  1. This checks if the response body matches the schema defined in the pet-schema.json file.

3. Handling XML Responses

While JSON is the most commonly used format for APIs, XML is still prevalent in many legacy systems and certain industries. REST Assured allows developers to handle XML responses efficiently.

Validating XML Responses

To handle XML responses, you need to set the Accept header to application/xml to inform the server that XML is expected in the response.

Example:

Java
package xml;

import org.testng.annotations.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;

public class XMLTests {

    @Test
    public void testJSONData() {
        given()
                .baseUri("https://petstore.swagger.io/v2")
        .when()
                .get("/pet/9223372036854760000")
        .then()
                .statusCode(200);
    }

    @Test
    public void testXMLData() {
        given()
                .baseUri("https://petstore.swagger.io/v2")
                .accept("application/xml")
        .when()
                .get("/pet/9223372036854760000")
        .then()
                .statusCode(200)
                .body("Pet.status", equalTo("pending"));
    }
}

Output:

Screenshot-2025-01-25-163420
xml test output

This checks that the status element in the XML response matches "available". "24.28"

4. Automating Complex API Flows

Real-world API testing often involves more than just sending a single request. It may involve creating resources, verifying them, and then deleting them, all within a single test flow.

Example: Automating GitHub API Flows

Creating a Repository

To create a repository on GitHub using the API, you can use the POST method with a JSON payload.

Example:

String payload = "{ \"name\": \"test-repo\", \"private\": false }";
given()
.auth().oauth2("<token>")
.body(payload)
.when()
.post("/user/repos")
.then()
.statusCode(201);

This creates a repository with the specified name.

Deleting a Repository

To delete the repository, you can use the DELETE method.

Example:

given()
.auth().oauth2("<token>")
.when()
.delete("/repos/<username>/test-repo")
.then()
.statusCode(204);

This deletes the repository and ensures no further data exists for the specified repository.

Combining the Flow

You can now combine both actions into a flow and assert the outcomes of each operation. This is useful for automating the lifecycle of resources in API testing.

5. Best Practices for REST Assured

Use Request Specifications

Centralizing common configurations like base URIs, authentication, headers, and other settings makes your tests more maintainable and easier to read.

Example:

RequestSpecification spec = new RequestSpecBuilder()
.setBaseUri("https://api.github.com/")
.setAuth(oauth2("<token>"))
.build();

Leverage Logs

Logging requests and responses helps in debugging and understanding test failures. You can log everything in your requests and responses to get more insight into the interaction.

Example:

given()
.log().all()
.when()
.get("/endpoint")
.then()
.log().body();

Dynamic Data Handling

API tests often require dynamic data such as user tokens or IDs that may change with each test run. Using variables for dynamic data helps ensure that your tests are adaptable to different test scenarios.

Comment

Explore