Introduction
In our previous post, we explored GET Requests in REST Assured, learning how to retrieve data from APIs. Now, we’ll dive into POST Requests, which are used to create new resources on the server. This guide is designed for beginners and experienced developers, providing clear explanations and practical examples to help you master POST requests in REST Assured.
Key Point: POST requests send data to an API to create new resources, such as adding a new user or post, and REST Assured simplifies this process with its intuitive syntax.
What is a POST Request?
A POST Request is an HTTP method used to send data to a server to create a new resource. Unlike GET requests, which retrieve data, POST requests typically include a request body (e.g., JSON or XML) containing the data for the new resource. For example, sending a POST request to /users
with a JSON payload can create a new user.
In REST Assured, POST requests are performed using the post()
method, often combined with headers, query parameters, or a request body to define the resource details.
Performing POST Requests in REST Assured
Let’s explore how to perform and validate POST requests using REST Assured, using the public API https://jsonplaceholder.typicode.com
for examples.
Option 1: Basic POST Request with JSON Body
The most common way to send a POST request is with a JSON request body, defined as a string.
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class BasicPostTest {
@Test
public void testBasicPost() {
RestAssured.baseURI = "https://jsonplaceholder.typicode.com";
String jsonBody = "{\"title\": \"Test Post\", \"body\": \"This is a test post\", \"userId\": 1}";
given()
.contentType("application/json")
.body(jsonBody)
.when()
.post("/posts")
.then()
.statusCode(201)
.body("title", equalTo("Test Post"))
.body("userId", equalTo(1))
.body("id", notNullValue());
}
}
Explanation:
contentType("application/json")
: Sets the Content-Type header to indicate a JSON payload.body(jsonBody)
: Sends the JSON string as the request body.post("/posts")
: Sends a POST request to create a new post.then()
: Validates the response:statusCode(201)
: Ensures the resource was created (201 Created).body("title", equalTo("Test Post"))
: Verifies the post’s title.body("userId", equalTo(1))
: Confirms the user ID.body("id", notNullValue())
: Checks that the server assigned an ID.
Important: Always set the correctContent-Type
header (e.g.,application/json
) to match the request body format, or the API may reject the request.
Option 2: POST Request with Java Object
For cleaner code, use a Java object as the request body. REST Assured automatically serializes the object to JSON if a library like Jackson is included.
First, ensure the Jackson dependency is in your pom.xml
:
com.fasterxml.jackson.core
jackson-databind
2.15.2
test
Now, create a Java class and use it in a POST request:
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
// Java class for the request body
class Post {
private String title;
private String body;
private int userId;
public Post(String title, String body, int userId) {
this.title = title;
this.body = body;
this.userId = userId;
}
// Getters and setters
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getBody() { return body; }
public void setBody(String body) { this.body = body; }
public int getUserId() { return userId; }
public void setUserId(int userId) { this.userId = userId; }
}
public class PostObjectTest {
@Test
public void testPostWithObject() {
RestAssured.baseURI = "https://jsonplaceholder.typicode.com";
Post post = new Post("Test Post", "This is a test post", 1);
given()
.contentType("application/json")
.body(post)
.when()
.post("/posts")
.then()
.statusCode(201)
.body("title", equalTo("Test Post"))
.body("userId", equalTo(1));
}
}
Explanation:
Post
: A Java class representing the JSON structure.body(post)
: REST Assured serializes thePost
object to JSON.- This approach reduces errors compared to writing JSON strings manually.
Option 3: POST Request with Request Specification
Use a Request Specification to reuse common settings like headers or base URI for POST requests.
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class PostWithSpecTest {
private static RequestSpecification requestSpec;
@BeforeAll
public static void setup() {
requestSpec = new RequestSpecBuilder()
.setBaseUri("https://jsonplaceholder.typicode.com")
.setContentType("application/json")
.build();
}
@Test
public void testPostWithSpec() {
String jsonBody = "{\"title\": \"Test Post\", \"body\": \"This is a test\", \"userId\": 1}";
given()
.spec(requestSpec)
.body(jsonBody)
.when()
.post("/posts")
.then()
.statusCode(201)
.body("title", equalTo("Test Post"));
}
}
Explanation:
setContentType("application/json")
: Sets the default content type in the specification.spec(requestSpec)
: Applies the specification, while the test provides the specific JSON body.
Pro Tip: Use Request Specifications for POST requests to centralize common settings, making tests more maintainable and reducing code duplication.
Step 1: Combining POST with Path and Query Parameters
POST requests can include path parameters or query parameters for more complex scenarios.
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class PostWithParamsTest {
@Test
public void testPostWithParams() {
RestAssured.baseURI = "https://jsonplaceholder.typicode.com";
String jsonBody = "{\"title\": \"Test Comment\", \"body\": \"This is a comment\", \"userId\": 1}";
given()
.contentType("application/json")
.pathParam("postId", 1)
.queryParam("userId", 1)
.body(jsonBody)
.when()
.post("/posts/{postId}/comments")
.then()
.statusCode(201)
.body("title", equalTo("Test Comment"));
}
}
Explanation:
pathParam("postId", 1)
: Specifies the post ID in the URL (/posts/1/comments
).queryParam("userId", 1)
: Adds a query parameter to filter or customize the request.- The test creates a comment for a specific post and validates the response.
Step 2: Extracting Response Data
You can extract the response from a POST request for further validation or processing.
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
public class PostExtractResponseTest {
@Test
public void testExtractPostResponse() {
RestAssured.baseURI = "https://jsonplaceholder.typicode.com";
String jsonBody = "{\"title\": \"Test Post\", \"body\": \"This is a test\", \"userId\": 1}";
Response response = given()
.contentType("application/json")
.body(jsonBody)
.when()
.post("/posts")
.then()
.statusCode(201)
.extract().response();
int id = response.path("id");
System.out.println("Created Post ID: " + id);
// Additional validation
assert id > 0;
}
}
Explanation:
extract().response()
: Extracts the full response for further processing.response.path("id")
: Retrieves theid
field from the JSON response.- This is useful for validating or storing the ID of the created resource.
Step 3: Verify Setup with pom.xml
Ensure your pom.xml
includes dependencies for REST Assured, JUnit, and Jackson (for JSON serialization):
io.rest-assured
rest-assured
5.4.0
test
org.junit.jupiter
junit-jupiter
5.10.2
test
org.hamcrest
hamcrest
2.2
test
com.fasterxml.jackson.core
jackson-databind
2.15.2
test
Run the tests using mvn test
or your IDE’s test runner to confirm the setup.
Tips for Beginners
- Validate Payloads: Ensure the request body matches the API’s expected structure.
- Use Java Objects: Prefer Java objects over JSON strings for cleaner code.
- Check Status Codes: Expect 201 for successful resource creation, or 200 if the API deviates from standard REST practices.
- Enable Logging: Use
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails()
to debug issues.
Troubleshooting Tip: If a POST request returns a 400 Bad Request error, verify the request body, Content-Type
header, and endpoint URL against the API documentation.
What’s Next?
In the next post, we’ll cover PUT Requests, exploring how to update resources using REST Assured. Stay tuned for more hands-on examples!