Skip to content
CodeKruPro

API Workflow - Authentication and Order

61/62

API Workflow - Authentication and Order

Real-world APIs require multi-step workflows, where one response feeds the next request. This assignment chains:

  1. Login: POST to /auth/login → read the logged-in user and the JWT token
  2. Create Order: POST to /orders with userId and productId, sending the token in an Authorization: Bearer <token> header → get the order confirmation

The order response includes expanded user and product data, for example user.name and product.name.

On this practice API, /orders does not check the token, so an order without it still succeeds here. Real order APIs answer 401 without one, so send it the way a real client would.

Task:

  1. Log in as admin / secret123 and print the user field after the label Logged in as: (never print the token itself; it changes every second)
  2. Create the order from the starter code with the Bearer header, and validate status 201
  3. Print the order ID, user name, product name, total and status as shown below

Expected output:

Logged in as: admin
Order ID: ORD-001
User: John Doe
Product: Wireless Mouse
Total: 29.99
Status: confirmed

About this lesson

REST Assured API chaining workflow: log in, then create an order with the token

Learn REST AssuredAdvancedAdvanced Topics

How it works

End-to-end API tests rarely stop at one call. A workflow test feeds the output of one response into the next request, the way a real client would. Here the first call is /auth/login. With the right username and password it returns 200 and two fields: token, a JWT made of three dot-separated parts that expires an hour after it was issued, and user, the username as a plain string. Wrong credentials get a 401. Because the expiry is stamped from the current time, the token text changes from one second to the next, which is why it should never appear in expected output.

The token goes into an Authorization header with the Bearer scheme, a space, then the token. header() builds that by hand; auth().oauth2() with the token sends the identical header. testkru's /orders does not verify the token, so the call succeeds without it, but sending it keeps the test honest for an API that does.

A successful order returns 201. orderId is built from the user ID, zero-padded to three digits after a prefix. user and product come back as expanded objects, total equals the product price, and status reports the order state. Note the change of shape: user was a string in the login answer but is an object here, so its name lives at user.name.

About the assignment

Log in as the admin user, create the order from the starter code with the token in a Bearer header, check that it was created, and print its details.

What you will do

  1. POST to /auth/login with the JSON content type and a body holding the admin username and password. Keep the token with getString() and print the user field after Logged in as:.
  2. POST to /orders, again with the JSON content type, and a body containing userId 1 and productId 2, adding an Authorization header that combines the Bearer prefix with the token.
  3. Assert status 201 with then().statusCode().
  4. Print the order ID, user.name, product.name, the total read with getDouble(), and the status, using the labels shown in the expected output.

Common mistakes

  • Dropping the space after Bearer

    The header value is the scheme, one space, then the token. Without the space the scheme is not recognised: testkru's protected endpoint looks for the word Bearer followed by a space and answers 401 otherwise, even though /orders here would let the order through.

  • Reading user as text in the order

    In the order response user is an object. getString() on it returns the whole map in brackets with id, name and email, not the name.

  • Reading the total with get()

    JsonPath returns a Float for that decimal, which is not equal to the Double literal of the same value. getDouble() gives the number you expect.

In a real test suite

In a JUnit 5 suite the login usually happens once, in a @BeforeAll method or a shared request specification that stores the Bearer header, and every test reuses it. Workflow tests then focus on business rules: a missing productId returns 400 with a message naming the field, and an unknown product ID returns 400 as well.

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.

Main.java
import io.restassured.RestAssured;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import io.restassured.http.ContentType;
import static io.restassured.RestAssured.*;

public class Main {
    public static void main(String[] args) {
        RestAssured.baseURI = "https://testkru.com/api";

        // Step 1: Log in
        // TODO: POST to /auth/login with admin/secret123
        // TODO: Keep the "token" field, and print "Logged in as: " + the "user" field

        // Step 2: Create an order, authenticated with the token
        // TODO: POST to /orders with body {"userId": 1, "productId": 2}
        //       and header Authorization = "Bearer " + token
        // Validate status 201
        // Print order details: orderId, user.name, product.name, total, status
    }
}