Skip to content
SDETRole
SDETRole

REST Assured interview question

How do you use JSON schema validation, filters and logging in a REST Assured framework?

advanced 5+ yrs #rest-assured#json-schema#filters#logging#reporting

Short answer

Use the json-schema-validator module's matchesJsonSchemaInClasspath to assert the response contract, kept in sync with the OpenAPI spec. Use filters (implementing Filter) for cross-cutting concerns: auth token injection and refresh, request/response logging on failure, correlation ids, and attaching traffic to reports.

Answer

These three features are what turn a pile of REST Assured tests into a framework that is easy to debug in CI.

JSON Schema validation

Add the io.rest-assured:json-schema-validator module (same version as REST Assured). Store schemas under src/test/resources/schemas.

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

given().spec(spec)
    .when().get("/orders/{id}", orderId)
    .then()
    .statusCode(200)
    .body(matchesJsonSchemaInClasspath("schemas/order.json"));

A schema is only as useful as its strictness:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "required": ["id", "status", "total", "lines"],
  "additionalProperties": false,
  "properties": {
    "id": { "type": "string", "pattern": "^[0-9a-f-]{36}$" },
    "status": { "enum": ["OPEN", "PAID", "SHIPPED", "CANCELLED"] },
    "total": { "type": "number", "minimum": 0 },
    "lines": { "type": "array", "minItems": 1 }
  }
}
  • Mark required fields, or the schema passes an empty object.
  • additionalProperties: false catches unexpected fields (including accidental data exposure) but breaks on harmless additions; decide per API.
  • The module is built on an older validator that implements JSON Schema draft-04 (and draft-03), so write schemas in draft-04 style. If you need newer drafts, validate the extracted body with a separate library such as networknt’s json-schema-validator.
  • Do not hand-maintain schemas that already exist in the OpenAPI spec. Extract or generate them from the spec in the build, or validate against the spec directly with a library such as Atlassian’s swagger-request-validator, which has a REST Assured filter.

Schema validation checks the provider against its own documented shape. It complements, but does not replace, value assertions and consumer contract tests.

Filters

A filter intercepts every request and response, like servlet middleware:

import io.restassured.filter.Filter;
import io.restassured.filter.FilterContext;
import io.restassured.response.Response;
import io.restassured.specification.FilterableRequestSpecification;
import io.restassured.specification.FilterableResponseSpecification;

public class AuthFilter implements Filter {
    private final TokenProvider tokens;

    public AuthFilter(TokenProvider tokens) { this.tokens = tokens; }

    @Override
    public Response filter(FilterableRequestSpecification req,
                           FilterableResponseSpecification res,
                           FilterContext ctx) {
        req.header("Authorization", "Bearer " + tokens.current());
        req.header("X-Correlation-Id", java.util.UUID.randomUUID().toString());
        Response response = ctx.next(req, res);
        if (response.statusCode() == 401 && tokens.refresh()) {
            req.removeHeader("Authorization");
            req.header("Authorization", "Bearer " + tokens.current());
            response = ctx.next(req, res);
        }
        return response;
    }
}

Register it once in the RequestSpecBuilder with addFilter(new AuthFilter(tokens)). Typical filters:

  • Auth injection and refresh, so tests never handle tokens.
  • Correlation ids, so a failing test can be traced in service logs.
  • Reporting: io.qameta.allure.restassured.AllureRestAssured attaches every request and response to the Allure report.
  • Contract validation against OpenAPI, as above.

Tests that check authentication itself must bypass the auth filter, so build a separate unauthenticated spec for them.

Logging that helps rather than floods

  • given().log().ifValidationFails() / then().log().ifValidationFails(), or enableLoggingOfRequestAndResponseIfValidationFails() on the config, prints traffic only for failing tests.
  • RequestLoggingFilter and ResponseLoggingFilter can write to a PrintStream. In parallel runs, writing to a shared System.out interleaves output from different tests, so prefer per-test capture (for example the Allure filter) over console logs.
  • Mask secrets: LogConfig.blacklistHeader("Authorization", "Cookie") replaces those header values in logs. Mask sensitive body fields in custom filters.

What interviewers look for

  • Correct schema validation setup and a view on schema strictness and OpenAPI sync.
  • Writing a custom Filter with ctx.next and using it for cross-cutting concerns.
  • Logging only on failure, masking secrets, and parallel-safe reporting.
  • Understanding where schema validation stops and contract testing begins.

A strong answer covers

  • Schema validation with the json-schema-validator module and matchesJsonSchemaInClasspath
  • Keeping schemas strict enough (required, additionalProperties) and in sync with OpenAPI
  • Custom Filter for cross-cutting concerns like auth or correlation ids
  • Logging only on failure and masking secrets
  • Attaching request/response to reports (Allure filter) and thread safety
Practise answering under time pressure

Type to search across SDETRole.

Full-text search by Pagefind · runs in your browser Open search page →