15_Integration_Patterns

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: