Core Concepts
Graph Compose makes it easy to build and manage complex API workflows. Here's what you need to know to get started.
๐ Any Workflow is Possible: Graph Compose is designed to be completely flexible, if you can dream it you can build it with complete confidence in durable execution. Graph Compose comes ready out of the box, requiring no changes to existing infrastructure.
Nodes ๐ต
Basic units of work that:
- โข Make HTTP requests to APIs
- โข Transform data with JSONata
- โข Handle retries and timeouts
Dependencies โก๏ธ
Control execution flow:
- โข Define execution order
- โข Enable parallel processing
- โข Manage data flow
Context ๐
Global workflow state:
- โข Available to all expressions
- โข Context is stored under context
- โข Previously executed nodes results are stored under [nodeId].result
JSONata ๐
Transform data between nodes:
- โข Powerful expression language for JSON
- โข Access data from any node using dot notation
- โข Transform, filter, and combine data seamlessly
Workflow Basics
A workflow in Graph Compose is represented as a directed acyclic graph (DAG). Think of a graph like a flowchart where each step (a node) performs an action, and arrows dictate the sequence and dependencies. In Graph Compose, each node typically represents an HTTP request.
This DAG structure ensures a clear, predictable execution order, prevents infinite loops (as it's 'acyclic', meaning no cycles), and allows independent nodes to run in parallel for efficiency.
Nodes are connected, allowing the output from one node (like an API response) to be transformed and used as input for subsequent nodes.
You have several options for defining these workflows:
- Code SDKs: Leverage our type-safe SDKs for maximum control, flexibility, and integration with your existing codebase.
- Visual Builder: Use the graphical interface (shown below) to quickly design, visualize, and manage workflow connections.
- Direct API (JSON): Define workflows by sending JSON definitions to our REST API, allowing for dynamic generation or augmentation from your custom applications.

Building a Real-World Workflow: E-commerce Order Processing
Let's illustrate the power of Graph Compose with a common scenario: processing an e-commerce order. This involves coordinating multiple API calls (fetching order details, checking/reserving inventory, processing payment) with reliability. While you could attempt to chain these calls manually, Graph Compose provides an enterprise-ready solution built on Temporal.io for durable, zero-deploy orchestration, freeing you from complex infrastructure management.
SOLUTION One Simple API, Zero Infrastructure
Graph Compose handles all the complexity for you:
- ๐ฏ Automatic Retries: Built-in retry policies for transient failures
- ๐ก๏ธ Error Boundaries: Sophisticated error handling and recovery
- ๐ Real-time Monitoring: Watch your workflow execute in real-time
- ๐ State Management: Durable execution with automatic state persistence
The Graph Compose Way ๐
Here's how you define the order processing workflow using Graph Compose:
const workflow = new GraphCompose()
// Define error boundary to handle rollback if inventory reservation fails
.errorBoundary("inventory_rollback", ["reserve_inventory"])
.post("https://your-api.com/api/inventory/release")
.withBody({
items: "{{results.get_order.items}}"
})
.end()
// Define workflow nodes in order of execution
.node("get_order")
.get("https://your-api.com/api/orders/{{context.orderId}}")
// Configure activity-level settings like retries
.withRetries({
maximumAttempts: 3,
initialInterval: "1s" // Uses exponential backoff
})
.end()
.node("check_inventory")
.post("https://your-api.com/api/inventory/check")
.withBody({ items: "{{results.get_order.items}}" })
.withDependencies(["get_order"]) // Requires order data
.end()
.node("reserve_inventory")
.post("https://your-api.com/api/inventory/reserve")
.withBody({ items: "{{results.get_order.items}}" })
.withDependencies(["check_inventory"]) // Only reserve after checking
.end()
.node("process_payment")
.post("https://your-api.com/api/payments")
.withBody({
orderId: "{{results.get_order.id}}",
amount: "{{results.get_order.total}}"
})
.withDependencies(["reserve_inventory"])
// Configure activity-level settings like timeouts
.withStartToCloseTimeout("30s")
.end();
// Execute the workflow with automatic retries, error handling, and monitoring
const result = await workflow.execute({ orderId: "123" });
These challenges highlight why manually orchestrating distributed systems is error-prone and difficult to maintain. Graph Compose offers the recommended, enterprise-grade solution. By leveraging Temporal.io, it handles durability, retries, state, and error handling automatically, letting you define resilient workflows declaratively and focus purely on your business logic.
To understand the benefits Graph Compose provides, let's look at how this same workflow might be built using a traditional, manual approach.
Compare: The Traditional (Manual) Approach That Breaks Down ๐ซ
Here's what the same e-commerce order processing workflow looks like when implemented manually with TypeScript, perhaps in a single serverless function. You can immediately see the challenges in managing timeouts, retries, state, and error handling.
Why This Breaks Down in Production ๐ฅ
๐ซ
Error Handling is Complex
- Partial Failures: What happens when only some items in
Promise.all
fail? - Cascading Failures: If inventory release fails after payment failure, you're left in an inconsistent state
- Retry Logic: Each operation needs its own retry strategy and backoff logic
- Error Recovery: How do you resume from failures? Restart or continue?
๐
Debugging is a Nightmare
- Flow Visibility: No way to see the workflow state in real-time
- Error Context: When something fails, which step failed and why?
- Logging Gaps: Console logs disappear in production
- State Tracking: What's the current state during issues?
๐ ๏ธ
Maintenance Becomes Impossible
- Code Complexity: Error handling overshadows business logic
- State Management: Need to track state for rollbacks and retries
- Monitoring: How do you track success rates and patterns?
- Testing: Testing all error paths becomes exponentially complex
๐๏ธ
Infrastructure Concerns
- Timeouts: This service must stay alive for the duration of the workflow, waiting for responses from all processes and services
- Durability: What happens if the server crashes mid-workflow?
- Resource Management: Need to manage connections and cleanup
These challenges compound as your workflows grow more complex. Graph Compose handles all of these concerns out of the box, letting you focus on your business logic instead of infrastructure complexity.
Want more examples?
Our hosted functions allow you to access a wide range of APIs and services, including Stripe, SendGrid, and more.
Next Steps
Ready to start building? Choose your path: