chainletWorkflowPipeline

使用 chainlet 优雅地编排复杂业务流程

chainlet 是一个轻量级的链式调用框架,让复杂业务流程变得清晰易懂

2024-03-10

在开发微服务应用时,我们经常需要处理复杂的业务流程。传统的方式容易导致代码嵌套过深、逻辑分散。为此,我们开发了 chainlet,一个轻量级的链式调用框架。

为什么需要 chainlet?

传统方式的问题

// 传统方式 - 嵌套过深
async function processOrder(order: Order) {
  const validated = await validateOrder(order);
  if (!validated.success) {
    throw new Error('Invalid order');
  }

  const inventory = await checkInventory(validated.data);
  if (!inventory.available) {
    throw { type: 'out_of_stock', items: inventory.missing };
  }

  const payment = await processPayment(validated.data);
  if (!payment.success) {
    throw { type: 'payment_failed', reason: payment.error };
  }

  return await confirmOrder(validated.data, payment);
}

chainlet 的优势

// chainlet 方式 - 清晰的流水线
const pipeline = chain()
  .use(validateOrder)
  .use(checkInventory)
  .use(processPayment)
  .use(confirmOrder)
  .handle(ValidationError, handleInvalidOrder)
  .handle(InventoryError, handleOutOfStock)
  .handle(PaymentError, { retry: 3, fallback: handlePaymentFailed });

const result = await pipeline.execute(order);

核心概念

Chain

链式调用的核心容器,按顺序执行中间件。

Middleware

中间件处理输入数据,可以:

  • 验证和转换数据
  • 调用外部服务
  • 决定是否继续执行

Handler

错误处理器,捕获和处理特定类型的错误。

高级用法

条件执行

chain()
  .use(checkUserStatus)
  .when(user => user.isPremium, premiumPipeline)
  .otherwise(freePipeline);

并行执行

chain()
  .parallel([
    fetchUserProfile,
    fetchUserOrders,
    fetchUserNotifications
  ])
  .use(combineUserData);

重试机制

chain()
  .use(unstableExternalService, {
    retry: 3,
    backoff: 'exponential',
    maxDelay: 5000
  });

实际应用场景

支付流程

const paymentPipeline = chain()
  .use(verifyPaymentMethod)
  .use(calculateAmount)
  .use(processPayment)
  .use(recordTransaction)
  .use(sendConfirmation);

数据导入

const importPipeline = chain()
  .use(parseCSVFile)
  .use(validateData)
  .batch(100, saveToDatabase)
  .use(generateReport);

总结

chainlet 让复杂业务流程变得:

  • 可读性强:像阅读故事一样理解业务流程
  • 易于测试:每个中间件可以独立测试
  • 灵活扩展:轻松添加或移除处理步骤

安装 chainlet:

npm install @rpamis/chainlet

希望 chainlet 能帮助大家更好地组织代码!