REST Assured
A Java DSL for testing REST APIs with fluent BDD-style syntax — the standard choice when your project is Java or Spring Boot and you want API tests in the same language and build pipeline as your application code.
The Hook: API Testing for Grown-ups
Postman is great for a quick check, but it's a "UI tool." If you're building a massive banking app, you don't want to click buttons to test 500 different API endpoints. You want a Code Tool. REST Assured is the industry standard for Java teams to automate API testing with speed and precision.
It reads like English, runs like lightning, and integrates perfectly with your existing Java build pipeline. No more "I forgot to save the collection" — your tests live in Git, right next to the code.
The Rule: The Contract First Principle
An API is a contract between the Frontend and the Backend. The Rule: Verify the Status, then the Data. If the status isn't 200 OK, don't even bother looking at the data. REST Assured makes this order mandatory in its syntax, keeping your tests logical and easy to debug.
The Analogy: The Postal Service
Think of an API call like sending a registered letter. The Headers are the address on the envelope. The Auth Token is your ID shown to the postie. The Body is the letter inside. REST Assured is the quality inspector at the post office checking that the envelope is addressed correctly, the ID is valid, and the letter isn't empty.
The Setup: Adding the DSL
To use REST Assured, add this to your pom.xml. We call it a "DSL" because it changes the way Java looks to make it feel like a testing language.
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.3.0</version>
<scope>test</scope>
</dependency>
The First Script: Given / When / Then
This is the magic of REST Assured. It uses the Given/When/Then pattern to structure your test:
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
test("Check user details") {
given()
.baseUri("https://api.example.com")
.header("Content-Type", "application/json")
.when()
.get("/users/1")
.then()
.statusCode(200)
.body("name", equalTo("Leanne Graham"))
.body("email", containsString("@"));
}
Senior engineer insight
The moment REST Assured clicked for me was when I realised it's not a testing tool bolted onto Java — it's a contract enforcer that happens to run inside your CI pipeline. On a payments project, we caught a backend developer quietly changing a transactionId field from Long to String in a response; Postman never would have flagged it, but our schema-validated REST Assured suite turned red within minutes and blocked the merge. That incident shifted how our whole team thought about API tests: they're not "extra work", they're the safety net that catches contract drift before it reaches mobile clients.
The most common mistake: teams write happy-path GET tests only and never validate POST/PUT request bodies or 4xx error shapes, so downstream consumers discover the broken contract in production.
The "Gotcha": The GPath Trap
When you want to find a value deep inside a JSON response, REST Assured uses something called GPath. It's powerful but picky. If your JSON is { "users": [{ "id": 1 }] }, you can't just ask for id.
The Fix: Use dot notation carefully. To get that ID, you've gotta use users[0].id. Always check your path in a JSON viewer before writing the test code!
The Framework: Hamcrest Matchers
REST Assured doesn't just check for equality; it uses Hamcrest Matchers for sophisticated validation:
greaterThan(0): Useful for checking ID fields.hasSize(5): Checks the length of a list.notNullValue(): Ensures a field isn't empty.anyOf(equalTo(200), equalTo(201)): Handles multiple success codes.
The NZ Example: Address Validator
In NZ, we often use the PostNZ Address API. Let's test a mock version of it.
test("Validate Wellington Postcode") {
given()
.queryParam("street", "101 Customhouse Quay")
.queryParam("city", "Wellington")
.when()
.get("/address/validate")
.then()
.statusCode(200)
.body("postcode", equalTo("6011"))
.body("region", equalTo("Wellington"));
}
From the field
A Wellington-based fintech was building an open-banking integration required under the NZ Commerce Commission's CDR framework. The team assumed their Spring Boot API was stable — they had unit tests, code reviews, and a manual Postman run before every release. What they hadn't accounted for was that the third-party consent service returned a different JSON structure when the user had more than one linked account; that path had never been Postman-tested because nobody thought to try it. After rolling out REST Assured with parameterised tests driven by a CSV of realistic account combinations, they found six hidden field-naming inconsistencies in the first run. The lesson that generalised: Postman is great for exploration, but any API path that carries real money needs code-based tests that can be data-driven and run on every commit.
The Pro Move: JSON Schema Validation
Checking every field manually is slow. Seniors use JSON Schema. A schema is a "Blueprint" of what the response should look like. With one line of code, you can validate that 100 fields all have the correct type and structure.
.then()
.assertThat()
.body(matchesJsonSchemaInClasspath("user-schema.json"));
The Challenge: Your Turn
We have a mock API at /api/v1/health that returns {"status": "up", "uptime": 12345}.
Your Task: Write a REST Assured test that checks the status code is 200, the "status" field is exactly "up", and the "uptime" is a number greater than 0.
Why teams fail here
- Hardcoded base URIs and auth tokens — teams embed environment-specific URLs and bearer tokens directly in test classes; the suite works locally, fails in CI, and leaks credentials into version control.
- Treating REST Assured as Postman in code — only testing happy-path 200 responses and never asserting on 400/401/422 shapes, so error-handling regressions slip straight to production.
- Ignoring JSON Schema validation — manually asserting 10-15 fields feels thorough, but when a backend team adds, renames, or removes fields the test still passes if you only checked the fields you knew about; schema validation catches the unknowns.
- No request/response logging on failure — when a test fails in CI at 2 a.m., teams have no evidence to debug; REST Assured's
.log().ifValidationFails()takes one line to add and saves hours of re-running to reproduce failures.
Key takeaway
REST Assured doesn't replace your test strategy — it makes your API contracts executable, so the moment the backend drifts from what the frontend expects, your pipeline catches it before a human does.