Skip to main content

Chained Multi-Domain Workflows

Welcome to the Chained Multi-Domain Workflows documentation!

While unit tests isolate individual functions, true integration testing verifies that independent microservices can communicate correctly in production. Rumour excels at orchestrating these multi-domain workflows by seamlessly passing state from one API boundary to another.

In this example, we will simulate an e-commerce checkout flow spanning three different microservices: a Users API, an Inventory API, and a Payments API.

1. The Scenario Structure​

Assume we have an integration test folder set up like this:

ecommerce_integration/
├── 1_register_user.toml
├── 2_reserve_inventory.toml
├── 3_process_payment.toml
└── workspace.env.toml

Our environment file points to the three distinct microservices:

workspace.env.toml:

users_api = "https://users.swahira.internal"
inventory_api = "https://inventory.swahira.internal"
payments_api = "https://payments.swahira.internal"

2. Defining the Workflow​

Step 1: User Registration​

First, we interact with the Users API to create a new customer.

1_register_user.toml:

name = "Register Customer"

[request]
method = "POST"
url = "{{users_api}}/register"

[body]
type = "json"
raw = '{"email": "customer_{{random}}@swahira.io"}'

[extract]
customer_id = "json.id"

[assert]
status = 201

Step 2: Inventory Reservation​

Next, we interact with the Inventory API. We must wait for customer_id from the previous step to attach the reservation to the correct user.

2_reserve_inventory.toml:

name = "Reserve Product"

[dependencies]
"1_register_user.toml" = "customer_id"

[request]
method = "POST"
url = "{{inventory_api}}/reserve"

[body]
type = "json"
raw = '{"customer_id": "{{customer_id}}", "product_sku": "SWA-PRO-1"}'

[extract]
reservation_id = "json.reservation_id"
total_amount = "json.price"

[assert]
status = 200

Step 3: Payment Processing​

Finally, we call the Payments API. This node requires two dependencies: it needs the customer_id from Step 1, and the reservation_id and total_amount from Step 2.

3_process_payment.toml:

name = "Process Checkout"

[dependencies]
"1_register_user.toml" = "customer_id"
"2_reserve_inventory.toml" = ["reservation_id", "total_amount"]

[request]
method = "POST"
url = "{{payments_api}}/charge"

[body]
type = "json"
raw = '{"customer_id": "{{customer_id}}", "reservation_id": "{{reservation_id}}", "amount": {{total_amount}}}'

[assert]
status = 200
"json.payment_status" = { equal = "SUCCESS" }

3. Workflow Execution​

When you execute this suite, Rumour automatically connects the dots across the different API domains, transferring the output of one microservice into the payload of the next.

rumour run ./ecommerce_integration/ -v

Execution Trace​

POST https://users.swahira.internal/register
✓ SUCCESS: ./ecommerce_integration/1_register_user.toml (112ms)
POST https://inventory.swahira.internal/reserve
✓ SUCCESS: ./ecommerce_integration/2_reserve_inventory.toml (215ms)
POST https://payments.swahira.internal/charge
✓ SUCCESS: ./ecommerce_integration/3_process_payment.toml (410ms)

╭──────────────────────────────────────────────────────────────────────────╮
│ RUMOUR EXECUTION REPORT │
├──────────────────────────────────────────────────────────────────────────┤
│ Total Requests: 3 │
│ Successful: 3 │
│ Failed: 0 │
│ Skipped: 0 │
│ Success Rate: 100.0% │
│ Total Time: 737ms │
╰──────────────────────────────────────────────────────────────────────────╯

✓ Successful Requests:
- ./ecommerce_integration/1_register_user.toml [201] [112ms]
- ./ecommerce_integration/2_reserve_inventory.toml [200] [215ms]
- ./ecommerce_integration/3_process_payment.toml [200] [410ms]

By chaining workflows in this manner, you can simulate incredibly complex, asynchronous business logic in a readable, maintainable format.