About this lesson
REST Assured: reuse one request specification across several endpoints
Learn REST AssuredIntermediateRequest Specification
How it works
A specification pays off when many requests share it. Build it once with the base URI, the content type and the credentials, and each call shrinks to the path plus whatever is unique about that request. When the base URI or the key changes, you edit one line instead of every test.
Settings in a spec apply to every request, even those that do not need them. setContentType(ContentType.JSON) makes REST Assured send Content-Type: application/json on a GET with no body, and the X-API-Key header goes to /users and /products too. Endpoints that do not care about a header simply ignore it, which is why one shared spec works for public and protected routes alike.
Each call still ends with its own check. then().statusCode(200) throws an AssertionError when the status differs, so a confirmation printed right after that line only appears when the check really held. That ordering turns the printed lines into a readable log of which endpoints passed.
About the assignment
Build a single spec with the base URI, JSON content type and API key, then reuse it to check three endpoints and confirm each one after its status check passes.
What you will do
- Create the spec with
RequestSpecBuilder:setBaseUri(),setContentType()withContentType.JSON,addHeader()for the API key, thenbuild(). - Using
given().spec(), GET/users/1, assert status 200 withthen().statusCode(), and print the users confirmation line. - Repeat with the same spec for
/auth/apikeyand print the auth confirmation line. - Repeat for
/products/1and print the products confirmation line.
Common mistakes
Printing before checking
If the confirmation line comes before
statusCode(200), it appears even when the call fails. Put the assertion first so that a printed line means the check passed.Building a new spec for each call
Creating three nearly identical specs defeats the purpose and invites drift when one copy is updated and the others are not. Build it once and pass the same object to every
spec()call.Expecting the spec to remember responses
A request specification only shapes what is sent. It holds no state from earlier calls, so a token or id you extract must be stored in a variable and added to the next request yourself.
In a real test suite
Frameworks commonly keep a small class of named specs, for example one for anonymous calls, one for a normal user and one for an admin, and each test picks the right one. Request-specific settings such as path parameters, query parameters or a body are added after spec() in the individual test.
Related lessons
- Headers SpecificationIntroduces the API key header inside a spec.
- Basic Response SpecificationMoves the repeated status checks into a reusable response spec.
- Validate Content-Type with MatchersCovers the ContentType enum used by setContentType().
To try one of these calls on any API endpoint without a task, open the Online Selenium Java Compiler (REST Assured is included).
Starter code
The editor above opens with this code. Fill in the TODO lines, then run and submit it.
import io.restassured.RestAssured;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import io.restassured.http.ContentType;
import io.restassured.builder.RequestSpecBuilder;
import static io.restassured.RestAssured.*;
public class Main {
public static void main(String[] args) {
// TODO: Create a single spec with baseUri, ContentType.JSON, and X-API-Key header
// TODO: Use it to:
// 1. GET /users/1 → validate status 200 → print "Users endpoint: OK"
// 2. GET /auth/apikey → validate status 200 → print "Auth endpoint: OK"
// 3. GET /products/1 → validate status 200 → print "Products endpoint: OK"
}
}