Skip to main content
Staff SDET Masterclass · REST Assured · Postman

REST API Testing: The Complete Engineering Guide

80% of business logic bugs live in backend services. Learn API testing from first principles: HTTP protocol anatomy, JWT authentication, BOLA security verification, Java REST Assured automation, and JSON Schema contract validation.

Author:TesterRank Lead SDET Team
Updated:October 2026 Edition
Stack:REST Assured 5.5+ • Java 17 • Postman / Newman
Depth:2,750+ Words • Production Code

1. Why API Testing? The Modern Test Automation Pyramid

In traditional QA teams, testing was treated as an inverted pyramid (the "ice cream cone" anti-pattern): 80% of test effort was spent creating slow, brittle UI tests in Selenium, while the backend API layer was ignored. When a button click failed, QA spent hours triaging whether the bug was a CSS locator break, a network timeout, or an actual backend calculation defect.

The Ideal Engineering Test Pyramid

UI Tests (10% of Suite) — End-to-End User Journeys

Only test critical user journeys (signup, complete checkout, fund transfer). Slower execution (3-8 seconds per test). High maintenance costs.

API / Integration Tests (30-40% of Suite) — The SDET Sweet Spot

Tests business logic, validations, authentication, database persistence, and external service contracts. Executes in milliseconds (50-200ms per call). Zero UI flakiness.

Unit Tests (50-60% of Suite) — Pure Code Functions

Written by developers in JUnit/Jest. Verifies isolated classes and algorithmic edge cases in microseconds.

2. Anatomy of an HTTP Request & Response

REST (Representational State Transfer) is built on the stateless HTTP/1.1 and HTTP/2 protocols. To write reliable API automation, you must master the structural components of every request and response:

Request Anatomy

  • Method: GET, POST, PUT, PATCH, DELETE
  • Base URI & Path: https://api.testerrank.com/v1/accounts
  • Query Parameters: Filter & sort: ?status=active&limit=20
  • Headers: Metadata like Content-Type: application/json and Authorization: Bearer <token>
  • Body: Payload payload for POST/PUT/PATCH (JSON)

Response Anatomy

  • Status Code: 200 OK, 201 Created, 401 Unauthorized
  • Response Headers: Server metadata (Date, Content-Length, X-Request-ID)
  • Response Body: Serialized JSON object or array representing system state
  • Response Latency: Time in milliseconds to complete round-trip (target < 300ms)

3. HTTP Methods & Idempotency Deep Dive

An HTTP method is idempotent if making the identical request N times produces the exact same server side-effect as making it once. Understanding idempotency is essential for designing resilient automated test retries:

MethodSafe?Idempotent?PurposeExpected Status Code
GETYesYesRetrieve representation of a resource without mutation200 OK
POSTNoNoCreate new subordinate entity. Repeating creates duplicates201 Created
PUTNoYesComplete replacement of existing resource at known URI200 OK / 204 No Content
PATCHNoGenerally NoPartial mutation of specific fields without replacing whole payload200 OK
DELETENoYesDelete resource at URI. Subsequent calls return 404 or 204204 No Content / 200 OK

4. HTTP Status Code Taxonomy

Never accept APIs that return 200 OK with an internal error object inside the JSON body (e.g., { "status": "error" }). This violates the HTTP specification. Ensure endpoints return accurate RFC status codes:

2xx Success

  • 200 OK: Request succeeded with payload.
  • 201 Created: Resource created (accompanies Location header).
  • 202 Accepted: Request accepted for asynchronous background queue processing.
  • 204 No Content: Succeeded, intentionally no response body (e.g., DELETE).

4xx Client Errors

  • 400 Bad Request: Malformed JSON or invalid schema format.
  • 401 Unauthorized: Unauthenticated — missing, expired, or invalid token.
  • 403 Forbidden: Authenticated, but user role lacks authorization.
  • 404 Not Found: Resource URI does not exist in database.
  • 409 Conflict: State conflict (e.g., duplicate email address).
  • 422 Unprocessable: Valid JSON syntax, but violates business rule.

5. Authentication Mechanisms & BOLA / IDOR Testing

Modern microservices use JSON Web Tokens (JWT) for stateless authorization. A JWT contains three Base64URL-encoded segments separated by periods: header.payload.signature.

Testing for Broken Object Level Authorization (BOLA / IDOR)

BOLA occurs when an API accepts an object identifier (like an account ID or order ID) from a client request, but fails to verify that the requesting user owns that object.

BolaSecurityTest.javaJava
// Step 1: Authenticate as User A (Attacker) and get token
String tokenUserA = authClient.login("attacker@test.com", "Password123!");

// Step 2: Attempt to read User B's private bank account using User A's token
given()
    .header("Authorization", "Bearer " + tokenUserA)
.when()
    .get("/api/v1/banking/accounts/ACC-VICTIM-9988")
.then()
    // Must return 403 Forbidden or 404 Not Found — NEVER 200 OK!
    .statusCode(anyOf(is(403), is(404)));

6. Postman Collections & Chai Assertions Masterclass

Postman is the industry standard for API exploration and smoke testing. Instead of manual verification, write automated Chai.js test assertions in the Tests tab of your requests:

PostmanAssertions.jsJavaScript
// 1. Assert HTTP Status Code
pm.test("Status code is 201 Created", function () {
    pm.response.to.have.status(201);
});

// 2. Assert Response Time SLA (< 400ms)
pm.test("Response time is under 400ms", function () {
    pm.expect(pm.response.responseTime).to.be.below(400);
});

// 3. Extract and assert JSON body fields
const response = pm.response.json();

pm.test("Account created with correct initial balance", function () {
    pm.expect(response).to.have.property("accountId");
    pm.expect(response.status).to.eql("ACTIVE");
    pm.expect(response.balance).to.be.at.least(0);
});

// 4. Save extracted ID into Environment Variable for downstream calls
pm.environment.set("currentAccountId", response.accountId);

7. Enterprise Java REST Assured Automation Framework

For enterprise CI/CD automation, Java SDETs write test suites using REST Assured. It employs a fluent BDD syntax: given() (prerequisites, headers, body) → when() (HTTP action) → then() (validations).

BankingApiTest.javaJava
package com.testerrank.api.tests;

import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

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

public class BankingApiTest {

    private RequestSpecification requestSpec;

    @BeforeClass
    public void setupSpecification() {
        requestSpec = new RequestSpecBuilder()
            .setBaseUri("https://www.testerrank.com")
            .setBasePath("/api")
            .setContentType(ContentType.JSON)
            .addHeader("Accept", "application/json")
            .build();
    }

    @Test(description = "Verify fund transfer API validates account balances")
    public void testFundTransferValidation() {
        String transferPayload = """
        {
            "fromAccount": "ACC-10029",
            "toAccount": "ACC-99482",
            "amount": 250.00,
            "currency": "USD"
        }
        """;

        given()
            .spec(requestSpec)
            .header("Authorization", "Bearer mock_jwt_token_sample_2026")
            .body(transferPayload)
        .when()
            .post("/practice/banking/transfers")
        .then()
            .statusCode(200)
            .body("status", equalTo("COMPLETED"))
            .body("referenceNumber", notNullValue())
            .body("remainingBalance", greaterThanOrEqualTo(0.0f))
            .time(lessThan(1000L)); // Assert response latency within 1000ms
    }
}

8. JSON Schema Validation & Contract Testing

Asserting individual JSON fields (like .body("status", equalTo("ACTIVE"))) verifies data correctness, but it does not protect against missing fields or type mutations. JSON Schema Validation validates the entire contract against a defined schema specification:

ContractValidationTest.javaJava
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;

@Test(description = "Verify customer account payload adheres to JSON Schema Draft-07")
public void verifyAccountContractSchema() {
    given()
        .spec(requestSpec)
    .when()
        .get("/practice/banking/accounts/ACC-10029")
    .then()
        .statusCode(200)
        // Validates entire response payload matches src/test/resources/schemas/account-schema.json
        .body(matchesJsonSchemaInClasspath("schemas/account-schema.json"));
}

9. The Negative Testing & Boundary Analysis Matrix

Amateur testers only test the happy path. Staff SDETs design comprehensive negative test matrices to ensure the server fails securely and gracefully:

Test ScenarioInput Payload / ConditionExpected StatusValidation Check
Negative Amount Transferamount: -500.00422 UnprocessableError message specifies amount must be > 0
Zero Amount Transferamount: 0.00422 UnprocessableBoundary check prevents empty debit transactions
Missing Required Fieldsomitted "toAccount" key400 Bad RequestSchema validation failure returned to client
Expired Bearer Tokenexp claim in past401 UnauthorizedAuthentication gateway rejects request before business logic
SQL Injection Probe"' OR 1=1 --"400 Bad RequestParameterized query prevents database syntax error

10. Running Postman Suites in CI/CD with Newman

Newman is the headless CLI runner for Postman. It allows you to run Postman collections in Jenkins, GitHub Actions, or GitLab pipelines without a desktop application:

terminalBash
# Install Newman globally via npm
npm install -g newman newman-reporter-htmlextra

# Execute Postman collection with environment variables and generate HTML report
newman run tests/postman_collection.json \
  --environment env/staging.json \
  --reporters cli,htmlextra \
  --reporter-htmlextra-export reports/api-report.html \
  --bail # Exit immediately with non-zero code if critical smoke tests fail

11. Frequently Asked Questions (FAQ)

Why is API testing faster and more reliable than UI browser testing?

API tests communicate directly with backend web services using lightweight HTTP payloads (JSON/XML). They bypass browser rendering engines, CSS transitions, JavaScript DOM parsing, and network image downloads. An API test completes in 50 to 200 milliseconds, whereas a comparable UI test takes 3 to 10 seconds. Furthermore, API tests are immune to UI redesigns, CSS class renaming, or layout refactoring, resulting in virtually zero locator-based flakiness.

What is the exact architectural difference between PUT and PATCH?

PUT is an idempotent method designed to completely replace the entire target resource with the provided payload. If you omit a field in a PUT request, that field is either overwritten with null or defaults to system settings. PATCH is a partial update method that modifies only the specific attributes provided in the payload while leaving existing fields unchanged. PUT is idempotent by definition (running it multiple times leaves the server in the identical state), while PATCH can be non-idempotent depending on business logic.

How do you test for Broken Object Level Authorization (BOLA / IDOR) in REST APIs?

BOLA (Broken Object Level Authorization), also known as Insecure Direct Object Reference (IDOR), is the #1 vulnerability on the OWASP API Security Top 10. To test for BOLA: Authenticate as User A and obtain a valid bearer token. Send a request to fetch or mutate User B's resource (e.g., `GET /api/v1/accounts/ACC-USER-B` or `PUT /api/v1/users/USER-B/profile`) using User A's Authorization header. A secure API must return 403 Forbidden or 404 Not Found. If it returns 200 OK with User B's data, a critical BOLA vulnerability exists.

What is JSON Schema Validation and why is it essential in microservices?

JSON Schema validation verifies that an API response adheres to a strict contract defining required field names, expected data types (string, integer, boolean, array), formatting constraints (email, uuid, regex), and allowed nullability. In microservices architectures, teams frequently update backend services. Schema validation catches contract breaking changes (such as a backend developer renaming `userId` to `user_id` or returning null instead of an empty array) before downstream web or mobile apps crash.

What is the purpose of RequestSpecification and ResponseSpecification in REST Assured?

RequestSpecification and ResponseSpecification are builder patterns in REST Assured that centralize common configuration. RequestSpecification bundles the base URI, headers (Authorization, Content-Type), and logging settings so you don't repeat them across dozens of test methods. ResponseSpecification bundles expected baseline assertions, such as verifying status codes under 300, checking Content-Type headers, or validating response time limits.

Ready to Practice API Automation?

Connect your Postman or Java REST Assured test suite directly to TesterRank's live practice APIs across Banking, Shopping, and Insurance.