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.