SoftwareTestPilot
API TestingPublished: 9 min read

REST Assured Java Tutorial: Complete 2026 Guide

Complete REST Assured Java tutorial for 2026. Setup, GET/POST/PUT/DELETE, authentication, JSON path, schema validation, reusable specs, and CI/CD integration.

Avinash Kamble
Avinash Kamble
Founder & QA Engineer at SoftwareTestPilot
Reviewed by Priyanka G.
Share:XLinkedInWhatsApp
REST Assured Java API testing — flat editorial illustration of a Java coffee cup beside a code window with GET, POST, PUT, DELETE method pills connected to a server stack.
REST Assured Java API testing — flat editorial illustration of a Java coffee cup beside a code window with GET, POST, PUT, DELETE method pills connected to a server stack.
In this article
  1. What is REST Assured?
  2. Prerequisites
  3. Project Setup
  4. Your First Test
  5. POST Requests
  6. PUT and DELETE
  7. Authentication
  8. JSON Path Assertions
  9. Schema Validation
  10. Reusable Specifications
  11. Common Patterns
  12. CI/CD Integration (GitHub Actions)
  13. Best Practices
  14. Continue your learning
  15. Frequently asked questions

Last updated: June 27, 2026 · 9 min read

REST Assured is the most popular Java library for API testing in 2026. This tutorial takes you from setup to production-ready API test suites in 60 minutes. Pair it with our API Testing Tutorial, Postman API Testing, and RestSharp C# Tutorial.

What is REST Assured?

REST Assured is a Java DSL (Domain Specific Language) for testing REST APIs. It provides a fluent, BDD-style syntax that makes API tests readable and maintainable. The library is documented at rest-assured.io.

given()
    .baseUri("https://api.example.com")
.when()
    .get("/users/1")
.then()
    .statusCode(200)
    .body("name", equalTo("Leanne Graham"));

Prerequisites

  • Java 17 LTS or 21 LTS
  • Maven 3.9+ or Gradle 8+
  • IDE — IntelliJ IDEA recommended

Project Setup

Maven (pom.xml)

<dependencies>
    <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>5.5.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.10.3</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Gradle (build.gradle)

dependencies {
    testImplementation 'io.rest-assured:rest-assured:5.5.0'
    testImplementation 'org.junit.jupiter:junit-jupiter:5.10.3'
}

Your First Test

import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
import org.junit.jupiter.api.Test;

public class FirstApiTest {

    @Test
    void getUserById() {
        given()
            .baseUri("https://jsonplaceholder.typicode.com")
        .when()
            .get("/users/{id}", 1)
        .then()
            .statusCode(200)
            .body("id", equalTo(1))
            .body("email", matchesPattern(".*@.*"))
            .time(lessThan(2000L));
    }
}

Run with mvn test.

POST Requests

@Test
void createUser() {
    given()
        .baseUri("https://api.example.com")
        .contentType("application/json")
        .body("""
            {
              "name": "Alice Johnson",
              "email": "alice@example.com",
              "role": "admin"
            }
            """)
    .when()
        .post("/users")
    .then()
        .statusCode(201)
        .body("id", notNullValue())
        .body("email", equalTo("alice@example.com"));
}

PUT and DELETE

@Test
void updateUser() {
    given()
        .baseUri("https://api.example.com")
        .contentType("application/json")
        .body("{ \"name\": \"Alice Updated\" }")
    .when()
        .put("/users/1")
    .then()
        .statusCode(200)
        .body("name", equalTo("Alice Updated"));
}

@Test
void deleteUser() {
    when()
        .delete("/users/1")
    .then()
        .statusCode(204);
}

Authentication

Bearer Token

String token = given()
    .body("{ \"email\": \"admin@example.com\", \"password\": \"Sup3rSecret!\" }")
    .contentType("application/json")
.when()
    .post("/auth/login")
.then()
    .extract().path("token");

given()
    .auth().oauth2(token)
.when()
    .get("/admin/users")
.then()
    .statusCode(200);

Basic Auth

given()
    .auth().basic("admin", "Sup3rSecret!")
.when()
    .get("/admin/dashboard")
.then()
    .statusCode(200);

JSON Path Assertions

given()
    .get("/users/1")
.then()
    .body("address.city", equalTo("Gwenborough"))
    .body("company.name", startsWith("Romaguera"))
    .body("id", greaterThan(0))
    .body("email", containsString("@"));

Schema Validation

Add the networknt validator:

<dependency>
    <groupId>com.networknt</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>1.4.0</version>
    <scope>test</scope>
</dependency>
@Test
void validateAgainstSchema() {
    InputStream schemaStream = getClass().getResourceAsStream("/schemas/user.json");

    given()
        .get("/users/1")
    .then()
        .body(matchesJsonSchema(schemaStream));
}

Reusable Specifications

public class ApiSpecs {
    public static RequestSpecification authSpec() {
        return new RequestSpecBuilder()
            .setBaseUri("https://api.example.com")
            .setContentType("application/json")
            .addHeader("X-API-Version", "v1")
            .build();
    }

    public static ResponseSpecification successResponse() {
        return new ResponseSpecBuilder()
            .expectStatusCode(200)
            .expectContentType("application/json")
            .build();
    }
}
@Test
void testWithSpec() {
    given()
        .spec(ApiSpecs.authSpec())
        .body("{ \"name\": \"Alice\" }")
    .when()
        .post("/users")
    .then()
        .statusCode(201);
}

Common Patterns

Data-driven testing

@ParameterizedTest
@CsvSource({
    "admin@example.com, Sup3rSecret!",
    "viewer@example.com, ViewerPass1!"
})
void loginTest(String email, String password) {
    given()
        .body(Map.of("email", email, "password", password))
    .when()
        .post("/auth/login")
    .then()
        .statusCode(200);
}

Extract and chain

String userId = given()
    .body(createUserPayload)
    .post("/users")
.then()
    .extract().path("id");

given()
    .pathParam("id", userId)
.when()
    .get("/users/{id}")
.then()
    .statusCode(200)
    .body("id", equalTo(userId));

File upload

given()
    .multiPart("file", new File("/path/to/file.pdf"))
    .post("/upload")
.then()
    .statusCode(200);

Mocking with WireMock

WireMockServer wireMock = new WireMockServer(8080);
wireMock.stubFor(get(urlEqualTo("/api/users"))
    .willReturn(aResponse().withBody("{ \"id\": 1 }")));

CI/CD Integration (GitHub Actions)

name: REST Assured Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with: { distribution: temurin, java-version: '17' }
      - run: mvn -B test

For broader CI patterns, see our GitHub Actions CI guide.

Best Practices

Do

  • Use specs for shared configuration and auth tokens
  • Validate JSON schemas on every test
  • Run in CI on every PR
  • Use JUnit 5 or TestNG for organization

Don't

  • Don't hardcode URLs or tokens
  • Don't skip schema validation
  • Don't share state across tests
  • Don't use REST Assured for UI testing (it's API only)

Frequently asked questions

Is REST Assured still relevant in 2026?

Yes — REST Assured 5.5+ is actively maintained and remains the de facto Java DSL for API testing.

What is the difference between REST Assured and Postman?

REST Assured is a Java library for code-first API testing. Postman is a GUI tool for exploration and collaboration. Most teams use both.

Can REST Assured test GraphQL?

Not directly — REST Assured is HTTP-focused, but you can POST GraphQL queries in the body. For deep GraphQL testing, use a GraphQL-specific client.

What Java version does REST Assured require?

Java 11+ is supported; Java 17 or 21 LTS is recommended for 2026 projects.

How do I run REST Assured tests in parallel?

Use JUnit 5's parallel execution or Maven Surefire's parallel mode. Each test gets its own request context.

How do I validate a JSON schema in REST Assured?

Use io.restassured.module.jsv.JsonSchemaValidator with .body(matchesJsonSchema(schemaFile)) in the .then() block.

Keep going

Practice these questions

Rehearse REST, Postman, REST Assured and contract-testing questions with worked examples.

Found this useful?
Share:XLinkedInWhatsApp

Was this article helpful?

Keep building your QA edge

Continue reading

Join the QA Community

Connect with fellow testers, share job leads, and get career advice.

Premium QA Resources

Stop Reinventing the Wheel. Upgrade Your QA Arsenal.

Take your testing skills from beginner to Lead Engineer. Supercharge your daily workflow with our premium digital resources.

  • ⚡ Ready-to-use testing strategy templates
  • 🔥 Advanced API & UI automation guides
  • ⏱️ Save 10+ hours a week on test planning
4.9/5 rating
Explore All Products

⭐⭐⭐⭐⭐ Trusted by 1,000+ Software Test Pilots • Instant Access