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");