Skip to main content

Workflow Integration Patterns

Learn common integration patterns for connecting workflows with external systems, APIs, and services in Axon OS.

Overview

Workflow integration enables seamless connectivity between Axon OS workflows and external systems, allowing you to automate complex business processes that span multiple platforms and services.

Key Integration Types

  • API Integration: Connect to REST, GraphQL, and SOAP APIs
  • Database Integration: Direct database connections and operations
  • File System Integration: File processing and storage operations
  • Message Queue Integration: Asynchronous messaging patterns
  • Cloud Service Integration: Integration with AWS, Azure, GCP services
  • Third-party Platform Integration: CRM, ERP, and business applications

API Integration Patterns

REST API Integration

interface RestApiConfig {
baseUrl: string;
authentication: {
type: 'bearer' | 'api-key' | 'oauth' | 'basic';
credentials: AuthCredentials;
};
headers: Record<string, string>;
timeout: number;
retryPolicy: RetryPolicy;
}

interface ApiRequest {
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
endpoint: string;
payload?: any;
queryParams?: Record<string, string>;
headers?: Record<string, string>;
}

// Example workflow node for API calls
const apiNode = {
id: 'api-call-001',
type: 'http-request',
config: {
method: 'POST',
url: 'https://api.example.com/users',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ${auth.token}'
},
body: {
name: '${input.userName}',
email: '${input.userEmail}',
department: '${input.department}'
},
timeout: 30000,
retries: 3
},
errorHandling: {
onError: 'retry',
maxRetries: 3,
retryDelay: 1000
}
};

GraphQL Integration

interface GraphQLConfig {
endpoint: string;
authentication: AuthConfig;
introspection: boolean;
subscriptions: boolean;
}

// GraphQL query node example
const graphqlNode = {
id: 'graphql-query-001',
type: 'graphql-request',
config: {
endpoint: 'https://api.example.com/graphql',
query: `
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
profile {
avatar
department
}
}
}
`,
variables: {
id: '${input.userId}'
},
headers: {
'Authorization': 'Bearer ${auth.token}'
}
}
};

Webhook Integration

interface WebhookConfig {
url: string;
method: 'POST' | 'PUT';
headers: Record<string, string>;
authentication: AuthConfig;
payload: any;
retryPolicy: RetryPolicy;
}

// Webhook trigger node
const webhookTrigger = {
id: 'webhook-trigger-001',
type: 'webhook-trigger',
config: {
path: '/webhooks/order-created',
method: 'POST',
authentication: {
type: 'signature',
secret: '${env.WEBHOOK_SECRET}'
},
validation: {
schema: {
type: 'object',
properties: {
orderId: { type: 'string' },
customerId: { type: 'string' },
amount: { type: 'number' }
},
required: ['orderId', 'customerId', 'amount']
}
}
}
};

Database Integration

SQL Database Connection

interface DatabaseConfig {
type: 'postgresql' | 'mysql' | 'sqlite' | 'mssql';
connection: {
host: string;
port: number;
database: string;
username: string;
password: string;
ssl?: boolean;
};
pool: {
min: number;
max: number;
idle: number;
};
}

// Database query node
const sqlQueryNode = {
id: 'sql-query-001',
type: 'sql-query',
config: {
connection: 'primary-db',
query: `
SELECT u.id, u.name, u.email, p.department
FROM users u
JOIN profiles p ON u.id = p.user_id
WHERE u.created_at >= $1
ORDER BY u.created_at DESC
`,
parameters: ['${input.startDate}'],
timeout: 30000
},
output: {
format: 'array',
transform: {
camelCase: true,
excludeFields: ['password', 'internal_id']
}
}
};

NoSQL Database Integration

// MongoDB integration example
const mongoQueryNode = {
id: 'mongo-query-001',
type: 'mongodb-query',
config: {
connection: 'mongodb-primary',
collection: 'orders',
operation: 'find',
query: {
status: 'pending',
created_at: {
$gte: '${input.startDate}',
$lte: '${input.endDate}'
}
},
projection: {
_id: 1,
order_id: 1,
customer_id: 1,
amount: 1,
items: 1
},
sort: { created_at: -1 },
limit: 100
}
};

Message Queue Integration

RabbitMQ Integration

interface RabbitMQConfig {
connection: {
hostname: string;
port: number;
username: string;
password: string;
vhost: string;
};
exchange: {
name: string;
type: 'direct' | 'topic' | 'fanout' | 'headers';
durable: boolean;
};
queue: {
name: string;
durable: boolean;
exclusive: boolean;
autoDelete: boolean;
};
}

// Message publisher node
const messagePublisher = {
id: 'rabbitmq-publish-001',
type: 'rabbitmq-publish',
config: {
connection: 'rabbitmq-primary',
exchange: 'order.events',
routingKey: 'order.created',
message: {
orderId: '${input.orderId}',
customerId: '${input.customerId}',
amount: '${input.amount}',
timestamp: '${workflow.timestamp}'
},
options: {
persistent: true,
mandatory: true,
immediate: false
}
}
};

// Message consumer trigger
const messageConsumer = {
id: 'rabbitmq-consume-001',
type: 'rabbitmq-consume',
config: {
connection: 'rabbitmq-primary',
queue: 'order.processing',
options: {
noAck: false,
exclusive: false,
priority: 0,
consumerTag: 'workflow-consumer'
},
prefetch: 10
}
};

Apache Kafka Integration

// Kafka producer node
const kafkaProducer = {
id: 'kafka-produce-001',
type: 'kafka-produce',
config: {
brokers: ['kafka1:9092', 'kafka2:9092'],
topic: 'user-events',
partition: null, // Auto-select partition
message: {
key: '${input.userId}',
value: {
event: 'user_created',
userId: '${input.userId}',
timestamp: '${workflow.timestamp}',
data: '${input.userData}'
},
headers: {
'source': 'axon-workflow',
'version': '1.0'
}
},
options: {
acks: 'all',
retries: 3,
batchSize: 16384
}
}
};

Cloud Service Integration

AWS Integration

// S3 file upload node
const s3UploadNode = {
id: 's3-upload-001',
type: 'aws-s3-upload',
config: {
credentials: {
accessKeyId: '${env.AWS_ACCESS_KEY}',
secretAccessKey: '${env.AWS_SECRET_KEY}',
region: 'us-east-1'
},
bucket: 'my-workflow-files',
key: 'uploads/${workflow.executionId}/${input.fileName}',
body: '${input.fileContent}',
metadata: {
'uploaded-by': 'axon-workflow',
'execution-id': '${workflow.executionId}'
},
serverSideEncryption: 'AES256'
}
};

// Lambda function invocation
const lambdaInvokeNode = {
id: 'lambda-invoke-001',
type: 'aws-lambda-invoke',
config: {
credentials: {
accessKeyId: '${env.AWS_ACCESS_KEY}',
secretAccessKey: '${env.AWS_SECRET_KEY}',
region: 'us-east-1'
},
functionName: 'process-user-data',
invocationType: 'RequestResponse',
payload: {
userId: '${input.userId}',
action: 'process',
metadata: {
executionId: '${workflow.executionId}',
timestamp: '${workflow.timestamp}'
}
}
}
};

Azure Integration

// Azure Blob Storage node
const azureBlobNode = {
id: 'azure-blob-001',
type: 'azure-blob-upload',
config: {
connectionString: '${env.AZURE_STORAGE_CONNECTION}',
containerName: 'workflow-files',
blobName: '${workflow.executionId}/${input.fileName}',
content: '${input.fileContent}',
options: {
blobHTTPHeaders: {
contentType: '${input.contentType}'
},
metadata: {
'uploaded-by': 'axon-workflow',
'execution-id': '${workflow.executionId}'
}
}
}
};

File System Integration

File Processing Patterns

// File reader node
const fileReaderNode = {
id: 'file-reader-001',
type: 'file-reader',
config: {
path: '${input.filePath}',
encoding: 'utf8',
format: 'csv', // csv, json, xml, xlsx
options: {
delimiter: ',',
hasHeader: true,
skipEmptyLines: true
},
chunked: {
enabled: true,
chunkSize: 1000 // Process 1000 rows at a time
}
}
};

// File writer node
const fileWriterNode = {
id: 'file-writer-001',
type: 'file-writer',
config: {
path: '/output/${workflow.executionId}/processed_data.json',
content: '${processing.result}',
format: 'json',
options: {
createDirectories: true,
overwrite: false,
backup: true
}
}
};

// Directory watcher trigger
const directoryWatcher = {
id: 'directory-watch-001',
type: 'directory-watcher',
config: {
path: '/input/files',
pattern: '*.csv',
events: ['created', 'modified'],
recursive: true,
debounce: 1000 // Wait 1 second for file changes to settle
}
};

Third-Party Platform Integration

CRM Integration (Salesforce)

const salesforceNode = {
id: 'salesforce-create-001',
type: 'salesforce-create',
config: {
authentication: {
type: 'oauth',
clientId: '${env.SALESFORCE_CLIENT_ID}',
clientSecret: '${env.SALESFORCE_CLIENT_SECRET}',
username: '${env.SALESFORCE_USERNAME}',
password: '${env.SALESFORCE_PASSWORD}',
securityToken: '${env.SALESFORCE_SECURITY_TOKEN}',
sandbox: false
},
sobject: 'Contact',
fields: {
FirstName: '${input.firstName}',
LastName: '${input.lastName}',
Email: '${input.email}',
Phone: '${input.phone}',
LeadSource: 'Web Form'
}
}
};

ERP Integration (SAP)

const sapRfcNode = {
id: 'sap-rfc-001',
type: 'sap-rfc-call',
config: {
connection: {
host: '${env.SAP_HOST}',
client: '${env.SAP_CLIENT}',
user: '${env.SAP_USER}',
password: '${env.SAP_PASSWORD}',
language: 'EN'
},
functionModule: 'RFC_READ_TABLE',
parameters: {
QUERY_TABLE: 'MARA',
DELIMITER: '|',
FIELDS: [
{ FIELDNAME: 'MATNR' },
{ FIELDNAME: 'MAKTX' },
{ FIELDNAME: 'MTART' }
],
OPTIONS: [
{ TEXT: "MATNR LIKE '${input.materialPattern}'" }
]
}
}
};

Authentication Patterns

OAuth 2.0 Flow

interface OAuth2Config {
authUrl: string;
tokenUrl: string;
clientId: string;
clientSecret: string;
scope: string[];
redirectUri: string;
grantType: 'authorization_code' | 'client_credentials' | 'refresh_token';
}

const oauthNode = {
id: 'oauth-auth-001',
type: 'oauth2-authenticate',
config: {
provider: 'google',
clientId: '${env.GOOGLE_CLIENT_ID}',
clientSecret: '${env.GOOGLE_CLIENT_SECRET}',
scope: ['https://www.googleapis.com/auth/drive.readonly'],
redirectUri: 'https://app.axonos.com/oauth/callback',
refreshToken: '${credentials.google.refreshToken}'
},
output: {
accessToken: 'auth.accessToken',
expiresIn: 'auth.expiresIn',
refreshToken: 'auth.refreshToken'
}
};

API Key Management

const apiKeyAuth = {
id: 'api-key-auth-001',
type: 'api-key-auth',
config: {
keyLocation: 'header', // header, query, body
keyName: 'X-API-Key',
keyValue: '${env.EXTERNAL_API_KEY}',
encoding: 'base64' // optional
}
};

Error Handling in Integration

Retry Strategies

interface RetryConfig {
maxAttempts: number;
backoffStrategy: 'fixed' | 'exponential' | 'linear';
baseDelay: number;
maxDelay: number;
jitter: boolean;
retryableStatusCodes: number[];
retryableErrors: string[];
}

const integrationWithRetry = {
id: 'api-call-with-retry',
type: 'http-request',
config: {
url: 'https://api.unreliable-service.com/data',
method: 'GET'
},
errorHandling: {
retry: {
maxAttempts: 5,
backoffStrategy: 'exponential',
baseDelay: 1000,
maxDelay: 30000,
jitter: true,
retryableStatusCodes: [500, 502, 503, 504],
retryableErrors: ['ECONNRESET', 'ETIMEDOUT']
},
fallback: {
type: 'alternative_service',
config: {
url: 'https://backup-api.service.com/data'
}
}
}
};

Circuit Breaker Pattern

const circuitBreakerConfig = {
id: 'circuit-breaker-001',
type: 'circuit-breaker',
config: {
failureThreshold: 5,
resetTimeout: 60000,
monitoringPeriod: 30000,
halfOpenMaxCalls: 3
},
wrappedNode: {
type: 'http-request',
config: {
url: 'https://api.external-service.com/endpoint'
}
}
};

Performance Optimization

Connection Pooling

interface ConnectionPoolConfig {
min: number;
max: number;
acquireTimeoutMillis: number;
idleTimeoutMillis: number;
reapIntervalMillis: number;
createRetryIntervalMillis: number;
}

const databasePool = {
type: 'connection-pool',
config: {
database: 'postgresql',
min: 2,
max: 20,
acquireTimeoutMillis: 30000,
idleTimeoutMillis: 600000,
reapIntervalMillis: 1000,
createRetryIntervalMillis: 200
}
};

Caching Strategies

const cachedApiCall = {
id: 'cached-api-call-001',
type: 'http-request',
config: {
url: 'https://api.example.com/slow-endpoint',
method: 'GET'
},
caching: {
enabled: true,
ttl: 300000, // 5 minutes
keyTemplate: 'api:${input.userId}:${input.category}',
strategy: 'cache-first',
conditions: {
cacheOn: ['2xx'],
skipCacheOn: ['4xx', '5xx']
}
}
};

Monitoring and Observability

Integration Metrics

interface IntegrationMetrics {
requestCount: number;
successCount: number;
errorCount: number;
averageResponseTime: number;
p95ResponseTime: number;
retryCount: number;
circuitBreakerStatus: 'closed' | 'open' | 'half-open';
}

const monitoringConfig = {
metrics: {
enabled: true,
interval: 30000,
tags: {
service: 'external-api',
environment: 'production'
}
},
alerting: {
errorRate: {
threshold: 0.05, // 5%
window: '5m'
},
responseTime: {
threshold: 5000, // 5 seconds
window: '1m'
}
}
};

Security Best Practices

Credential Management

  • Store sensitive credentials in environment variables or secure vaults
  • Use short-lived tokens when possible
  • Implement credential rotation policies
  • Never log or expose credentials in workflow outputs

Network Security

  • Use HTTPS/TLS for all external communications
  • Implement proper certificate validation
  • Use VPN or private networks for sensitive integrations
  • Apply network firewall rules and IP whitelisting

Data Protection

  • Encrypt sensitive data in transit and at rest
  • Implement data masking for logs and monitoring
  • Apply data retention policies
  • Use secure data transformation techniques

Common Integration Patterns

Fan-Out Pattern

const fanOutPattern = {
trigger: 'order-created',
parallel: [
{ node: 'update-inventory' },
{ node: 'send-confirmation-email' },
{ node: 'update-analytics' },
{ node: 'notify-shipping' }
],
joinStrategy: 'wait-all'
};

Scatter-Gather Pattern

const scatterGatherPattern = {
scatter: {
type: 'parallel-requests',
nodes: [
{ id: 'price-service-a', url: 'https://price-a.com/quote' },
{ id: 'price-service-b', url: 'https://price-b.com/quote' },
{ id: 'price-service-c', url: 'https://price-c.com/quote' }
]
},
gather: {
type: 'aggregate-results',
strategy: 'best-price',
timeout: 10000
}
};

Saga Pattern

const sagaPattern = {
steps: [
{
action: 'reserve-inventory',
compensation: 'release-inventory'
},
{
action: 'charge-payment',
compensation: 'refund-payment'
},
{
action: 'ship-order',
compensation: 'cancel-shipment'
}
],
onFailure: 'compensate-all'
};

Testing Integration Workflows

Mock Services

const mockServiceConfig = {
id: 'mock-payment-service',
type: 'mock-http-service',
config: {
port: 3001,
routes: [
{
path: '/charge',
method: 'POST',
response: {
status: 200,
body: {
transactionId: 'mock-${random.uuid}',
status: 'success',
amount: '${request.body.amount}'
}
},
delay: 1000 // Simulate network delay
}
]
}
};

Integration Testing

const integrationTest = {
name: 'Order Processing Integration Test',
setup: {
mockServices: ['payment-service', 'inventory-service'],
testData: './test-data/orders.json'
},
workflow: 'order-processing-workflow',
assertions: [
{
type: 'api-call-made',
service: 'payment-service',
endpoint: '/charge'
},
{
type: 'output-contains',
field: 'orderId',
pattern: /^ORD-\d+$/
},
{
type: 'execution-time',
maxDuration: 30000
}
]
};

Need Help?