Perfect — now this becomes a proper training-ready REST Assured doc aligned with your syllabus + your local API (json-server) 👍 👉 As per your rule: ✔ Only step headers formatted for Google Doc ✔ Content under each step ✔ Uses your local API ( http://localhost:3000 ) 🔹 pre requisite — Understanding API Testing (Rest Assured Context) Till now you used Postman for manual testing. Now you will use Java (Rest Assured) to automate the same APIs. Postman = manual clicks Rest Assured = code execution + automatic validation Rest Assured helps in: automation repeatable tests CI/CD integration 🔹pre requisite 2 — Introduction to Rest Assured Rest Assured is a Java library used for API testing. Core structure: given() .when() .then(); Meaning: given → request setup when → API call then → validation 🔹 pre requisite 3 — Setup REST Assured Project (Local API) Create Maven project → Add dependency: io.rest-assured rest-assured 5.3.0 Set base URI: baseURI = "http://localhost:3000"; Perfect — now this is the right way to learn Rest Assured 👍 👉 Step-by-step 👉 Each step isolated 👉 Using real API: Restful Booker 👉 Multiple examples for clarity 🔹 STEP 1 — Setup Base URI (Common for All APIs) // This will be used in all requests import io.restassured.RestAssured; RestAssured.baseURI = "https://restful-booker.herokuapp.com"; 👉 Avoid repeating full URL in every request 🔹 STEP 2 — GET Booking IDs (Basic GET API) import static io.restassured.RestAssured.*; given() .when() .get("/booking") .then() .statusCode(200); 👉 This returns list of booking IDs 🔹 STEP 3 — GET Booking Details (Path Parameter Example) given() .when() .get("/booking/1") .then() .statusCode(200); 👉 Fetch details of booking with ID = 1 🔹 STEP 4 — Validate Response Body (JSON Validation) import static org.hamcrest.Matchers.*; given() .when() .get("/booking/12") .then() .statusCode(200) .body("firstname", notNullValue()) .body("totalprice", greaterThan(0)); 👉 Validates: firstname exists price > 0 🔹 STEP 5.1 — Create Booking (POST Request) given() .header("Content-Type", "application/json") .body("{\n" + " \"firstname\": \"Wasim\",\n" + " \"lastname\": \"Ansari\",\n" + " \"totalprice\": 1000,\n" + " \"depositpaid\": true,\n" + " \"bookingdates\": {\n" + " \"checkin\": \"2024-01-01\",\n" + " \"checkout\": \"2024-01-05\"\n" + " },\n" + " \"additionalneeds\": \"Breakfast\"\n" + "}") .when() .post("/booking") .then() .statusCode(200); 👉 Creates a new booking Perfect — this is where real learning starts 🔥 Same API, same step — just different ways to pass body (very important for interviews) 🔹 STEP 5.2 — Passing Body as String (Current Way) given() .header("Content-Type", "application/json") .body("{\"firstname\":\"Wasim\",\"lastname\":\"Ansari\"}") .when() .post("/booking") .then() .statusCode(200); 👉 Hardcoded JSON ❌ Not scalable ✔ Good for quick testing 🔹 STEP 5.3 — Passing Body using Java Map (MOST PRACTICAL 🔥) import java.util.HashMap; HashMap body = new HashMap<>(); body.put("firstname", "Wasim"); body.put("lastname", "Ansari"); body.put("totalprice", 1000); body.put("depositpaid", true); given() .header("Content-Type", "application/json") .body(body) .when() .post("/booking") .then() .statusCode(200); 👉 Java → JSON conversion automatically ✔ Clean ✔ Dynamic 🔹 STEP 5.4 — Passing Nested JSON using Map HashMap bookingDates = new HashMap<>(); bookingDates.put("checkin", "2024-01-01"); bookingDates.put("checkout", "2024-01-05"); HashMap body = new HashMap<>(); body.put("firstname", "Wasim"); body.put("lastname", "Ansari"); body.put("totalprice", 1000); body.put("depositpaid", true); body.put("bookingdates", bookingDates); given() .header("Content-Type", "application/json") .body(body) .when() .post("/booking") .then() .statusCode(200); 👉 Handles complex JSON ✔ Very important in real APIs 🔹 STEP 5.5 — Passing Body using POJO (BEST PRACTICE ⭐) Create Class: class Booking { public String firstname; public String lastname; public int totalprice; } Use it: Booking b = new Booking(); b.firstname = "Wasim"; b.lastname = "Ansari"; b.totalprice = 1000; given() .header("Content-Type", "application/json") .body(b) .when() .post("/booking") .then() .statusCode(200); 👉 Java object → JSON automatically ✔ Cleanest ✔ Framework friendly 🔹 STEP 5.6 — Passing Body from JSON File booking.json { "firstname": "Wasim", "lastname": "Ansari" } Code: import java.io.File; given() .header("Content-Type", "application/json") .body(new File("booking.json")) .when() .post("/booking") .then() .statusCode(200); 👉 External data ✔ Best for large payloads 🔹 STEP 5.7 — Passing Body using String Builder (Dynamic) String body = "{ \"firstname\": \"" + "Wasim" + "\" }"; given() .header("Content-Type", "application/json") .body(body) .when() .post("/booking") .then() .statusCode(200); 👉 Dynamic but messy ❌ Avoid in frameworks 🔹 STEP 6 — Extract Booking ID (Important for Next Steps) int bookingId = given() .header("Content-Type", "application/json") .body("...same JSON...") .when() .post("/booking") .then() .extract().path("bookingid"); System.out.println("Booking ID: " + bookingId); 👉 Dynamic value → used later 🔹 STEP 7 — Authentication (Generate Token) String token = given() .header("Content-Type", "application/json") .body("{\"username\":\"admin\",\"password\":\"password123\"}") .when() .post("/auth") .then() .extract().path("token"); System.out.println("Token: " + token); 👉 Required for update/delete 🔹 STEP 8 — Update Booking (PUT Request) given() .header("Content-Type", "application/json") .header("Cookie", "token=" + token) .body("{\n" + " \"firstname\": \"Updated\",\n" + " \"lastname\": \"User\",\n" + " \"totalprice\": 2000,\n" + " \"depositpaid\": false,\n" + " \"bookingdates\": {\n" + " \"checkin\": \"2024-02-01\",\n" + " \"checkout\": \"2024-02-05\"\n" + " },\n" + " \"additionalneeds\": \"Lunch\"\n" + "}") .when() .put("/booking/" + bookingId) .then() .statusCode(200); 👉 Full update 🔹 STEP 9 — Partial Update (PATCH Request) given() .header("Content-Type", "application/json") .header("Cookie", "token=" + token) .body("{\"firstname\":\"PartialUpdate\"}") .when() .patch("/booking/" + bookingId) .then() .statusCode(200); 👉 Updates only selected fields 🔹 STEP 10 — Delete Booking (DELETE Request) given() .header("Cookie", "token=" + token) .when() .delete("/booking/" + bookingId) .then() .statusCode(201); 👉 Deletes booking 🔹 STEP 11 — Validate Deletion (Negative Test) given() .when() .get("/booking/" + bookingId) .then() .statusCode(404); 👉 Confirms deletion 🔹 STEP 12 — Multiple Query Parameter Example given() .queryParam("firstname", "Wasim") .when() .get("/booking") .then() .statusCode(200); 👉 Filters results 🔹 STEP 13 — Header Validation Example given() .when() .get("/booking") .then() .header("Content-Type", containsString("json")); 🔹 STEP 14 — End-to-End Flow (Real Scenario) // 1. Create booking // 2. Extract bookingId // 3. Generate token // 4. Update booking // 5. Delete booking // 6. Validate deletion 🔹 STEP 15 — Serialization and Deserialization in Java Serialization = Java object → JSON Deserialization = JSON → Java object Used for clean request/response handling. 🔹 STEP 16 — Deserialize JSON Response String name = given() .when() .get("/users/1") .then() .extract().path("name"); Extracts data from response. 🔹 STEP 17 — Authentication and Authorization in REST APIs For local API (json-server), auth is not enforced by default. For real APIs: https://restful-booker.herokuapp.com Authentication → login → token Authorization → use token Example: given() .header("Authorization", "Bearer token") .when() .get("/secure") .then() .statusCode(200); Ex - String token = given () .header( "Content-Type" , "application/json" ) .body( "{ \" username \" : \" admin \" , \" password \" : \" password123 \" }" ) .when() .post( "/auth" ) .then() .statusCode( 200 ) .extract() .path( "token" ); System. out .println(token); given () .header( "Content-Type" , "application/json" ) .header( "Cookie" , "token=" + token) .body( "{ \n " + " \" firstname \" : \" Harper \" , \n " + " \" lastname \" : \" Quinn \" , \n " + " \" totalprice \" : 345, \n " + " \" depositpaid \" : false, \n " + " \" bookingdates \" : { \n " + " \" checkin \" : \" 2020-08-01 \" , \n " + " \" checkout \" : \" 2020-08-04 \"\n " + " }, \n " + " \" additionalneeds \" : \" Cab Service \"\n " + "}" ) .when() .put( "/booking/" + bookingId) .then() .statusCode( 200 ); } 🔹 STEP 18 — JSON Basics (What is JSON) JSON = key-value format used in APIs Example: { "name": "Wasim" } 🔹 STEP 19 — JSONPath and Query JSON body("name", equalTo("Wasim")); Used to read JSON response. 🔹 STEP 20— Expressions in JSONPath body("[0].name", equalTo("Wasim")); Access array elements. 🔹 STEP 21— Deserialize JSON Array to List List names = given() .when() .get("/users") .then() .extract().path("name"); 🔹 STEP 22— Deserialize JSON Response to Array String[] names = given() .when() .get("/users") .then() .extract().as(String[].class); 🔹 STEP 23— API Documentation Understanding Use Swagger / API docs to understand: endpoints request/response auth 🔹 STEP 24— REST API Automation Framework (Basic Thinking) Framework includes: base class utilities test classes 🔹 STEP 25— REST API Test in Cucumber Write BDD style: Given user calls GET users API When request is sent Then status code should be 200 🔹 STEP 26— Convert JSON Request Body to POJO Create Java class: class User { public String name; } Use: .body(new User("Wasim")) 🔹 STEP 27— Convert JSON Response Body to POJO User user = given() .when() .get("/users/1") .then() .extract().as(User.class); 🔹 STEP 28— Separation of Test Layer with API Services Keep: test logic separate API calls separate Improves maintainability. 🔹 STEP 29— Implementation of REST Routes Define endpoints centrally: String USERS = "/users"; 🔹 STEP 30— Implementation of Generics in API Framework Reusable methods for: GET POST PUT 🔹 STEP 31— Refactoring for Request Headers Create common headers method: given().header("Content-Type","application/json"); 🔹 STEP 32— Share Test Context Pass data between tests (like token, id) 🔹 STEP 33— Share Scenario Context Used in Cucumber to share data between steps. 🔹 STEP 34— Implement Configuration Reader Read config from file: baseUrl=http://localhost:3000