On this page8 sections
CommandsIntermediate7-9 min reference

REST Assured

Java DSL for testing REST APIs. The given().when().then() syntax reads like a BDD spec and pairs naturally with JUnit 5 / TestNG.

Setup & Configuration

Maven dependency

<dependencies>
  <dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>5.4.0</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>5.4.0</version>
    <scope>test</scope>
  </dependency>
</dependencies>

Gradle dependency

testImplementation 'io.rest-assured:rest-assured:5.4.0'
testImplementation 'io.rest-assured:json-schema-validator:5.4.0'

Static imports

import static io.restassured.RestAssured.*;
import static io.restassured.matcher.RestAssuredMatchers.*;
import static org.hamcrest.Matchers.*;
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;

Base URI and path

@BeforeAll
static void setup() {
  RestAssured.baseURI = "https://api.example.com";
  RestAssured.basePath = "/v2";
  RestAssured.port = 443;
}

Logging

given()
  .log().all()                        // log full request
  .header("Authorization", "Bearer x")
.when()
  .get("/users")
.then()
  .log().ifValidationFails()          // log only on failure
  .statusCode(200);

GET Requests

Basic GET

given()
.when().get("/users/42")
.then().statusCode(200);

Query parameters

given()
  .queryParam("page", 1)
  .queryParam("size", 20)
  .queryParam("sort", "name")
.when()
  .get("/users")
.then()
  .statusCode(200);
 
// Map form
Map<String, Object> params = Map.of("page", 1, "size", 20);
given().queryParams(params).when().get("/users");

Path parameters

given()
  .pathParam("id", 42)
.when()
  .get("/users/{id}")
.then()
  .statusCode(200);
 
// Multiple path params
given()
  .pathParams("userId", 42, "orderId", 1001)
.when()
  .get("/users/{userId}/orders/{orderId}");

Headers

given()
  .header("Authorization", "Bearer abc123")
  .header("Accept", "application/json")
  .headers(Map.of("X-Request-ID", "uuid", "X-API-Version", "2"))
.when()
  .get("/profile");

POST / PUT / DELETE Requests

POST with raw JSON body

String body = """
  {
    "name": "Ada",
    "email": "ada@example.com"
  }
  """;
 
given()
  .contentType(ContentType.JSON)
  .body(body)
.when()
  .post("/users")
.then()
  .statusCode(201);

POST with POJO serialization

class User {
  public String name;
  public String email;
  public User(String name, String email) {
    this.name = name; this.email = email;
  }
}
 
given()
  .contentType(ContentType.JSON)
  .body(new User("Ada", "ada@example.com"))
.when()
  .post("/users")
.then()
  .statusCode(201);

REST Assured serializes POJOs via Jackson or Gson if either is on the classpath.

PUT and PATCH

given()
  .contentType(ContentType.JSON)
  .pathParam("id", 42)
  .body(Map.of("email", "new@example.com"))
.when()
  .put("/users/{id}")     // or .patch("/users/{id}")
.then()
  .statusCode(200);

DELETE

given()
  .pathParam("id", 42)
.when()
  .delete("/users/{id}")
.then()
  .statusCode(204);

Form data and multipart

given()
  .contentType(ContentType.URLENC)
  .formParam("username", "ada")
  .formParam("password", "secret")
.when()
  .post("/login");
 
given()
  .multiPart("file", new File("avatar.png"), "image/png")
  .multiPart("name", "Ada")
.when()
  .post("/upload");

Response Validation

Status, time, and content type

given()
.when()
  .get("/users")
.then()
  .statusCode(200)
  .time(lessThan(2000L))
  .contentType(ContentType.JSON)
  .header("X-Total-Count", notNullValue());

JSON body assertions

.then()
  .body("name", equalTo("Ada"))
  .body("email", endsWith("@example.com"))
  .body("roles", hasItems("admin", "editor"))
  .body("items.size()", greaterThan(0))
  .body("items[0].name", equalTo("first"))
  .body("items.id", hasItem(42))
  .body("items.findAll { it.active == true }.size()", greaterThan(0));

Hamcrest matchers

import static org.hamcrest.Matchers.*;
 
equalTo("x")               // strict equality
equalToIgnoringCase("X")
containsString("ad")
startsWith("Ad")
endsWith("ce")
matchesPattern("\\d+")
hasItems(1, 2, 3)
hasSize(5)
hasKey("id")
empty()
not(empty())
nullValue()
notNullValue()
greaterThan(0)
lessThanOrEqualTo(100)
allOf(greaterThan(0), lessThan(100))
anyOf(equalTo("a"), equalTo("b"))

JSON schema validation

schema.json on the classpath:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["id", "name", "email"],
  "properties": {
    "id":    { "type": "integer" },
    "name":  { "type": "string" },
    "email": { "type": "string", "format": "email" }
  }
}
given()
.when()
  .get("/users/42")
.then()
  .body(matchesJsonSchemaInClasspath("schema.json"));

Authentication

Basic

given().auth().basic("user", "pass")
.when().get("/secure");

Pre-emptive Basic

Sends the auth header on the first request — no 401 round-trip.

given().auth().preemptive().basic("user", "pass")
.when().get("/secure");

OAuth 2.0 (token only)

given().auth().oauth2("eyJhbGciOi...")
.when().get("/me");

Digest

given().auth().digest("user", "pass")
.when().get("/digest-protected");

Custom auth via header

given().header("Authorization", "Bearer " + token)
.when().get("/me");

Extracting Response Data

Extract single value

String token = given()
  .body(Map.of("username", "ada", "password", "secret"))
.when()
  .post("/login")
.then()
  .statusCode(200)
.extract()
  .path("access_token");

Extract full response

Response response = given()
.when()
  .get("/users/42")
.then()
  .statusCode(200)
.extract()
  .response();
 
String name              = response.jsonPath().getString("name");
List<String> roles       = response.jsonPath().getList("roles");
int count                = response.jsonPath().getInt("count");
String contentType       = response.getHeader("Content-Type");
Map<String, String> ck   = response.getCookies();
String body              = response.asString();

Deserialize to POJO

class User {
  public int id;
  public String name;
  public String email;
}
 
User user = given()
.when().get("/users/42")
.then().statusCode(200)
.extract().as(User.class);
 
System.out.println(user.email);
 
// List of POJOs
List<User> users = given()
.when().get("/users")
.then().statusCode(200)
.extract().jsonPath().getList(".", User.class);

Request & Response Specifications

Reuse common request setup and response checks across many tests.

Request specification

RequestSpecification authJsonSpec = new RequestSpecBuilder()
  .setBaseUri("https://api.example.com")
  .setBasePath("/v2")
  .setContentType(ContentType.JSON)
  .addHeader("Authorization", "Bearer " + token)
  .build();
 
given().spec(authJsonSpec)
  .pathParam("id", 42)
.when()
  .get("/users/{id}")
.then()
  .statusCode(200);

Response specification

ResponseSpecification okJson = new ResponseSpecBuilder()
  .expectStatusCode(200)
  .expectContentType(ContentType.JSON)
  .expectResponseTime(lessThan(2000L))
  .build();
 
given().spec(authJsonSpec)
.when().get("/users")
.then().spec(okJson);

Filters & Logging

Filters intercept requests/responses for logging, mocking, or token refresh.

Built-in logging filters

import io.restassured.filter.log.RequestLoggingFilter;
import io.restassured.filter.log.ResponseLoggingFilter;
 
given()
  .filter(new RequestLoggingFilter())
  .filter(new ResponseLoggingFilter())
.when().get("/users");

Conditional logging

given()
.when().get("/users")
.then()
  .log().ifStatusCodeIsEqualTo(500)
  .log().ifValidationFails();

Custom filter — auto-refresh expired token

public class TokenRefreshFilter implements Filter {
  @Override
  public Response filter(FilterableRequestSpecification req,
                         FilterableResponseSpecification res,
                         FilterContext ctx) {
    Response response = ctx.next(req, res);
    if (response.getStatusCode() == 401) {
      String fresh = TokenStore.refresh();
      req.removeHeader("Authorization");
      req.header("Authorization", "Bearer " + fresh);
      response = ctx.next(req, res);
    }
    return response;
  }
}
 
given().filter(new TokenRefreshFilter())
.when().get("/me");