Integration Patterns
What are Integration Patterns?
Integration patterns show how to connect Baba Yaga programs with external systems, APIs, and other services while maintaining functional purity through the ..emit
and ..listen
pattern.
Basic Integration Concepts
Emit and Listen Pattern
/* Emit events to external systems */
..emit "user_created" {id: 123, name: "Alice"};
..emit "data_processed" {count: 42, success: true};
/* Listen for external events */
..listen "user_created" handle_user_created;
..listen "data_processed" handle_data_processed;
State Management
/* Get current state from external system */
current_state : ..listen;
/* Process based on state */
user_id : current_state.user_id;
user_data : current_state.user_data;
/* Emit processed result */
..emit "user_processed" {
id: user_id,
processed_data: transform user_data
};
API Integration
HTTP Request Pattern
/* Emit HTTP requests */
..emit {
action: "http_request",
method: "GET",
url: "https://api.example.com/users/123"
};
/* Emit POST request with data */
..emit {
action: "http_request",
method: "POST",
url: "https://api.example.com/users",
data: {name: "Alice", email: "alice@example.com"}
};
API Response Handling
/* Listen for API responses */
..listen "api_response" handle_api_response;
handle_api_response : response ->
when response.success is
true then
..out "API call successful:";
..out response.data
false then
..out "API call failed:";
..out response.error;
Database Integration
Database Operations
/* Emit database queries */
..emit {
action: "db_query",
type: "select",
table: "users",
where: {id: 123}
};
/* Emit insert operation */
..emit {
action: "db_query",
type: "insert",
table: "users",
data: {name: "Bob", email: "bob@example.com"}
};
Database Response Processing
/* Process database results */
..listen "db_result" handle_db_result;
handle_db_result : result ->
when result.type = "select" then
users : result.data;
processed_users : map @format_user users;
..out "Found " + t.length users + " users";
processed_users
_ then result.data;
File System Integration
File Operations
/* Emit file operations */
..emit {
action: "file_operation",
type: "read",
path: "/data/users.json"
};
/* Emit write operation */
..emit {
action: "file_operation",
type: "write",
path: "/output/processed.json",
content: processed_data
};
File Processing
/* Process file contents */
..listen "file_result" handle_file_result;
handle_file_result : result ->
when result.type = "read" then
data : parse_json result.content;
processed : transform_data data;
processed
_ then result;
Event-Driven Architecture
Event Processing Pipeline
/* Process incoming events */
process_event : event ->
when event.type = "user_created" then
user : event.data;
validated_user : validate_user user;
when validated_user.valid is
true then
..emit "user_validated" validated_user.data;
validated_user.data
false then
..emit "validation_failed" validated_user.errors;
null
_ then event.data;
Event Handlers
/* Register event handlers */
..listen "user_created" process_event;
..listen "order_placed" process_event;
..listen "payment_received" process_event;
External Service Integration
Third-Party API Integration
/* Integrate with external service */
integrate_payment : order ->
payment_data : {
amount: order.total,
currency: "USD",
customer_id: order.customer_id
};
..emit {
action: "external_api",
service: "stripe",
endpoint: "/payments",
method: "POST",
data: payment_data
};
payment_data;
Service Response Handling
/* Handle external service responses */
..listen "external_api_response" handle_external_response;
handle_external_response : response ->
when response.service = "stripe" then
when response.success is
true then
..emit "payment_successful" response.data;
response.data
false then
..emit "payment_failed" response.error;
null
_ then response;
Real-World Integration Example
E-commerce Order Processing
/* Complete order processing pipeline */
process_order : order ->
/* Step 1: Validate order */
validation_result : validate_order order;
when validation_result.valid is
false then
..emit "order_invalid" validation_result.errors;
null
_ then
/* Step 2: Check inventory */
..emit {
action: "db_query",
type: "select",
table: "inventory",
where: {product_id: order.product_id}
};
/* Step 3: Process payment */
payment_result : integrate_payment order;
/* Step 4: Update inventory */
..emit {
action: "db_query",
type: "update",
table: "inventory",
where: {product_id: order.product_id},
data: {quantity: decrement_quantity order.quantity}
};
/* Step 5: Send confirmation */
..emit {
action: "email",
to: order.customer_email,
subject: "Order Confirmed",
template: "order_confirmation",
data: order
};
{order_id: order.id, status: "processed"};
Error Handling in Integration
Graceful Degradation
/* Handle integration failures */
safe_api_call : api_request ->
..emit api_request;
/* Set timeout for response */
timeout_result : wait_for_response 5000;
when timeout_result.timeout is
true then
..emit "api_timeout" api_request;
{error: "API timeout", fallback: true}
_ then timeout_result.response;
Retry Logic
/* Retry failed operations */
retry_operation : operation max_retries ->
attempt_operation : attempt ->
when attempt > max_retries then
..emit "max_retries_exceeded" operation;
{error: "Max retries exceeded"}
_ then
result : operation;
when result.error is
true then
delay : power 2 attempt; /* Exponential backoff */
..emit "retry_attempt" {attempt: attempt, delay: delay};
retry_operation operation max_retries
false then result;
attempt_operation 1;
Testing Integration
Mock External Services
/* Test integration without real services */
test_payment_integration : ->
/* Mock order */
test_order : {
id: "test_123",
total: 100,
customer_id: "cust_456"
};
/* Test payment integration */
result : integrate_payment test_order;
/* Verify emitted events */
..assert "Payment data emitted" result.amount = 100;
..assert "Payment data emitted" result.currency = "USD";
..out "Payment integration test passed";
Integration Test Patterns
/* Test complete integration flow */
test_order_flow : ->
/* Test order */
test_order : {
id: "test_123",
product_id: "prod_789",
quantity: 2,
customer_email: "test@example.com",
total: 50
};
/* Process order */
result : process_order test_order;
/* Verify result */
..assert "Order processed successfully" result.status = "processed";
..assert "Order ID preserved" result.order_id = "test_123";
..out "Order flow test passed";
Best Practices
Keep Integration Pure
/* Good: Pure function with explicit side effects */
process_data : data ->
transformed : transform data;
..emit "data_processed" transformed;
transformed;
/* Avoid: Hidden side effects */
bad_process : data ->
..emit "processing_started"; /* Hidden side effect */
transform data;
Use Structured Events
/* Good: Structured event data */
..emit {
type: "user_created",
timestamp: now(),
data: {id: 123, name: "Alice"},
metadata: {source: "web_form", version: "1.0"}
};
/* Avoid: Unstructured events */
..emit "user_created Alice 123"; /* Hard to parse */
Handle Errors Gracefully
/* Good: Explicit error handling */
safe_integration : request ->
when request.valid is
false then
..emit "integration_error" {request: request, error: "Invalid request"};
null
_ then
result : call_external_service request;
when result.error is
true then
..emit "service_error" result;
result.fallback_value
false then result.data;
Next Steps
Now that you understand integration patterns, explore:
- Error Handling for robust error management
- Advanced Combinators for complex integration patterns
- Best Practices for writing maintainable code