Skip to Content
SDK & PluginsContract Flow

Contract Flow

Use contract.flow() to verify that multiple endpoints work together correctly — create then retrieve, purchase then refund, register then login.

When to use

  • Cross-endpoint verification: one endpoint’s output feeds the next
  • Lifecycle testing: create → read → update → delete
  • State machines: order placed → paid → shipped → delivered

For single-endpoint specs, use contract.http() instead.

Basic flow

import { contract, configure } from "@glubean/sdk"; const { api } = configure({ http: { prefixUrl: "{{BASE_URL}}" }, }); export const userLifecycle = contract.flow("user-lifecycle") .http("create", { endpoint: "POST /users", client: api, body: { email: "flow@example.com", password: "secure123" }, expect: { status: 201 }, }) .returns((res) => ({ id: res.id })) .http("retrieve", { endpoint: "GET /users/:id", client: api, params: (state) => ({ id: state.id }), expect: { status: 200 }, }) .returns((res) => ({ id: res.id })) .http("delete", { endpoint: "DELETE /users/:id", client: api, params: (state) => ({ id: state.id }), expect: { status: 204 }, }) .build();

How it works

  1. Each .http() step sends one HTTP request
  2. .returns(res => state) extracts data from the response for the next step
  3. params, body, and headers can be functions that receive the current state
  4. Steps execute in order — the flow stops on the first failure

State passing

The flow carries state between steps via .returns():

.http("create-order", { endpoint: "POST /orders", client: api, body: { items: [{ productId: "p1", qty: 2 }] }, expect: { status: 201 }, }) .returns((res) => ({ orderId: res.id, total: res.total })) .http("pay", { endpoint: "POST /orders/:id/pay", client: api, params: (state) => ({ id: state.orderId }), body: (state) => ({ amount: state.total }), expect: { status: 200 }, })

Combining with contract.http()

Each endpoint in a flow should also have its own contract.http() for comprehensive case coverage. The flow verifies that endpoints work together; contract.http() verifies that each endpoint handles all cases.

// Spec cases for the create endpoint export const createUser = contract.http("create-user", { endpoint: "POST /users", client: api, cases: { success: { description: "...", body: {...}, expect: { status: 201 } }, duplicate: { description: "...", body: {...}, expect: { status: 409 } }, }, }); // Flow verifying endpoints work together export const userLifecycle = contract.flow("user-lifecycle") .http("create", { endpoint: "POST /users", ... }) .returns(res => ({ id: res.id })) .http("get", { endpoint: "GET /users/:id", ... }) .build();
Last updated on