Q26 of 40 · REST Assured

How would you build a REST Assured framework from scratch for a 100-engineer team?

REST AssuredSeniorrest-assuredframework-designarchitectureservice-layerapi-testing

Short answer

Short answer: Layer a BaseApiTest with RequestSpecBuilder and ResponseSpecBuilder, env-config loaded from properties or a config library, a token-refresh helper, and an Allure filter for reporting. Wrap REST Assured in a service layer so test methods call service.getUser(id) rather than fluent chains — the framework is the service layer, not the raw DSL.

Detail

A framework at scale needs four layers:

1. Configuration: load baseUri, credentials, and timeouts from environment variables or a config library (Owner, Typesafe Config). Never hard-code. Resolve at @BeforeAll and inject into specs.

2. Spec builders (BaseApiTest): RequestSpecification with shared headers, auth, content type, logging filter. ResponseSpecification with content-type and SLA assertions. Built once per suite, never per test.

3. Service layer — hide REST Assured behind typed methods:

public class UserService {
    private final ApiClient client;
    public User createUser(CreateUserRequest req) { ... }
    public User getUser(int id) { ... }
    public void deleteUser(int id) { ... }
}

Test code calls userService.createUser(req) — if you later swap REST Assured for another library, only this layer changes.

4. Reporting: register AllureRestAssured as a filter in RequestSpecBuilder so every request/response appears as an attachment on the Allure step. Annotate test methods with @Feature, @Story, @Severity.

Team scale concerns: enforce the BaseApiTest contract in code review, use Checkstyle/ArchUnit to prevent direct RestAssured.* static calls outside the service layer, and provide a starter module with examples.

// EXAMPLE

FrameworkOverview.java

// Config layer
public class ApiConfig {
    private static final Config cfg = ConfigFactory.create(Config.class);
    interface Config { String apiBaseUrl(); String apiToken(); }
    public static String baseUrl() { return cfg.apiBaseUrl(); }
    public static String token()   { return cfg.apiToken(); }
}

// Base test layer
public abstract class BaseApiTest {
    protected static RequestSpecification  reqSpec;
    protected static ResponseSpecification resSpec;

    @BeforeAll static void init() {
        reqSpec = new RequestSpecBuilder()
            .setBaseUri(ApiConfig.baseUrl())
            .addHeader("Authorization", "Bearer " + ApiConfig.token())
            .setContentType(ContentType.JSON)
            .addFilter(new AllureRestAssured())
            .log(LogDetail.ALL)
            .build();
        resSpec = new ResponseSpecBuilder()
            .expectContentType(ContentType.JSON)
            .expectResponseTime(lessThan(3000L), MILLISECONDS)
            .build();
    }
}

// Service layer
public class UserService {
    private final RequestSpecification spec;
    public UserService(RequestSpecification spec) { this.spec = spec; }

    public User createUser(Map<String, Object> body) {
        return given(spec).body(body)
            .when().post("/users")
            .then().spec(resSpec).statusCode(201)
            .extract().as(User.class);
    }
}

// Test — no REST Assured in sight
class UserApiTest extends BaseApiTest {
    private UserService users;
    @BeforeEach void setup() { users = new UserService(reqSpec); }

    @Test void createUser_returnsUser() {
        User u = users.createUser(Map.of("name", "Alice", "email", "a@b.com"));
        assertThat(u.getId()).isPositive();
    }
}

// WHAT INTERVIEWERS LOOK FOR

The four-layer model (config, specs, service layer, reporting), motivation for hiding REST Assured behind a service layer (maintainability, testability), and team-scale enforcement mechanisms (ArchUnit, Checkstyle). This separates engineers who have built frameworks from those who have only written tests.

// COMMON PITFALL

Putting all framework code in a giant BaseApiTest with hundreds of helper methods. This becomes unmaintainable — the service-layer pattern separates concerns and makes individual service clients independently testable and replaceable.