inngest-middleware
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseInngest Middleware
Inngest中间件
Master Inngest middleware to handle cross-cutting concerns like logging, error tracking, dependency injection, and data transformation. Middleware runs at key points in the function lifecycle, enabling powerful patterns for observability and shared functionality.
These skills are focused on TypeScript. For Python or Go, refer to the Inngest documentation for language-specific guidance. Core concepts apply across all languages.
掌握Inngest中间件,处理日志、错误追踪、依赖注入和数据转换等横切关注点。中间件在函数生命周期的关键节点运行,为可观测性和共享功能提供强大的实现模式。
本技能聚焦于TypeScript。 对于Python或Go语言,请参考Inngest documentation获取语言特定的指导。核心概念适用于所有语言。
What is Middleware?
什么是中间件?
Middleware allows code to run at various points in an Inngest client's lifecycle - during function execution, event sending, and more. Think of middleware as hooks into the Inngest execution pipeline.
When to use middleware:
- Observability: Add logging, tracing, or metrics
- Dependency injection: Share client instances across functions
- Data transformation: Encrypt/decrypt, validate, or enrich data
- Error handling: Custom error tracking and alerting
- Authentication: Validate user context or permissions
中间件允许代码在Inngest客户端的生命周期各个阶段运行——包括函数执行、事件发送等场景。可以将中间件视为Inngest执行流程中的钩子。
何时使用中间件:
- 可观测性: 添加日志、追踪或指标
- 依赖注入: 在多个函数间共享客户端实例
- 数据转换: 加密/解密、验证或丰富数据
- 错误处理: 自定义错误追踪和告警
- 身份验证: 验证用户上下文或权限
Middleware Lifecycle
中间件生命周期
Middleware can be registered at client-level (affects all functions) or function-level (affects specific functions).
中间件可以注册在客户端级别(影响所有函数)或函数级别(影响特定函数)。
Execution Order
执行顺序
typescript
const inngest = new Inngest({
id: "my-app",
middleware: [
loggingMiddleware, // Runs 1st
errorMiddleware // Runs 2nd
]
});
inngest.createFunction(
{
id: "example",
middleware: [
authMiddleware, // Runs 3rd
metricsMiddleware // Runs 4th
]
},
{ event: "test" },
async () => {
/* function code */
}
);Order matters: Client middleware runs first, then function middleware, in the order specified.
typescript
const inngest = new Inngest({
id: "my-app",
middleware: [
loggingMiddleware, // 第1个运行
errorMiddleware // 第2个运行
]
});
inngest.createFunction(
{
id: "example",
middleware: [
authMiddleware, // 第3个运行
metricsMiddleware // 第4个运行
]
},
{ event: "test" },
async () => {
/* 函数代码 */
}
);顺序很重要: 客户端中间件先运行,然后是函数级中间件,按照指定的顺序执行。
Creating Custom Middleware
创建自定义中间件
Basic Middleware Structure
基础中间件结构
typescript
import { InngestMiddleware } from "inngest";
const loggingMiddleware = new InngestMiddleware({
name: "Logging Middleware",
init() {
// Setup phase - runs when client initializes
const logger = setupLogger();
return {
// Function execution lifecycle
onFunctionRun({ ctx, fn }) {
return {
beforeExecution() {
logger.info("Function starting", {
functionId: fn.id,
eventName: ctx.event.name,
runId: ctx.runId
});
},
afterExecution() {
logger.info("Function completed", {
functionId: fn.id,
runId: ctx.runId
});
},
transformOutput({ result }) {
// Log function output
logger.debug("Function output", {
functionId: fn.id,
output: result.data
});
// Return unmodified result
return { result };
}
};
},
// Event sending lifecycle
onSendEvent() {
return {
transformInput({ payloads }) {
logger.info("Sending events", {
count: payloads.length,
events: payloads.map((p) => p.name)
});
// Return unmodified payloads
return { payloads };
}
};
}
};
}
});typescript
import { InngestMiddleware } from "inngest";
const loggingMiddleware = new InngestMiddleware({
name: "Logging Middleware",
init() {
// 初始化阶段 - 客户端初始化时运行
const logger = setupLogger();
return {
// 函数执行生命周期
onFunctionRun({ ctx, fn }) {
return {
beforeExecution() {
logger.info("函数启动", {
functionId: fn.id,
eventName: ctx.event.name,
runId: ctx.runId
});
},
afterExecution() {
logger.info("函数完成", {
functionId: fn.id,
runId: ctx.runId
});
},
transformOutput({ result }) {
// 记录函数输出
logger.debug("函数输出", {
functionId: fn.id,
output: result.data
});
// 返回未修改的结果
return { result };
}
};
},
// 事件发送生命周期
onSendEvent() {
return {
transformInput({ payloads }) {
logger.info("发送事件", {
count: payloads.length,
events: payloads.map((p) => p.name)
});
// 返回未修改的负载
return { payloads };
}
};
}
};
}
});Python Implementation
Python实现
Python middleware follows a similar pattern. See Dependency Injection Reference for complete Python examples.
undefinedPython中间件遵循类似的模式。完整的Python示例请参阅Dependency Injection Reference。
Dependency Injection
依赖注入
Share expensive or stateful clients across all functions. See Dependency Injection Reference for detailed patterns.
在所有函数间共享资源密集型或有状态的客户端。有关详细模式,请参阅Dependency Injection Reference。
Quick Example - Built-in DI
快速示例 - 内置DI
typescript
import { dependencyInjectionMiddleware } from "inngest";
const inngest = new Inngest({
id: 'my-app',
middleware: [
dependencyInjectionMiddleware({
openai: new OpenAI(),
db: new PrismaClient(),
}),
],
});
// Functions automatically get injected dependencies
inngest.createFunction(
{ id: "ai-summary" },
{ event: "document/uploaded" },
async ({ event, openai, db }) => {
// Dependencies available in function context
const summary = await openai.chat.completions.create({
messages: [{ role: "user", content: event.data.content }],
model: "gpt-4",
});
await db.document.update({
where: { id: event.data.documentId },
data: { summary: summary.choices[0].message.content }
});
}
);typescript
import { dependencyInjectionMiddleware } from "inngest";
const inngest = new Inngest({
id: 'my-app',
middleware: [
dependencyInjectionMiddleware({
openai: new OpenAI(),
db: new PrismaClient(),
}),
],
});
// 函数会自动获取注入的依赖
inngest.createFunction(
{ id: "ai-summary" },
{ event: "document/uploaded" },
async ({ event, openai, db }) => {
// 依赖在函数上下文中可用
const summary = await openai.chat.completions.create({
messages: [{ role: "user", content: event.data.content }],
model: "gpt-4",
});
await db.document.update({
where: { id: event.data.documentId },
data: { summary: summary.choices[0].message.content }
});
}
);Built-in Middleware
内置中间件
Inngest provides pre-built middleware for common use cases. See Built-in Middleware Reference for complete implementation details.
Inngest为常见使用场景提供了预构建的中间件。完整的实现细节请参阅Built-in Middleware Reference。
Encryption Middleware
加密中间件
typescript
import { encryptionMiddleware } from "inngest";
const inngest = new Inngest({
id: "my-app",
middleware: [
encryptionMiddleware({
key: process.env.ENCRYPTION_KEY
// Automatically encrypt/decrypt sensitive data
})
]
});typescript
import { encryptionMiddleware } from "inngest";
const inngest = new Inngest({
id: "my-app",
middleware: [
encryptionMiddleware({
key: process.env.ENCRYPTION_KEY
// 自动加密/解密敏感数据
})
]
});Sentry Error Tracking
Sentry错误追踪
typescript
import { sentryMiddleware } from "inngest";
const inngest = new Inngest({
id: "my-app",
middleware: [
sentryMiddleware({
dsn: process.env.SENTRY_DSN
// Auto-capture errors and performance data
})
]
});typescript
import { sentryMiddleware } from "inngest";
const inngest = new Inngest({
id: "my-app",
middleware: [
sentryMiddleware({
dsn: process.env.SENTRY_DSN
// 自动捕获错误和性能数据
})
]
});Common Middleware Patterns
常见中间件模式
Metrics and Performance Tracking
指标与性能追踪
typescript
const metricsMiddleware = new InngestMiddleware({
name: "Metrics Tracking",
init() {
return {
onFunctionRun({ ctx, fn }) {
let startTime: number;
return {
beforeExecution() {
startTime = Date.now();
metrics.increment("inngest.step.started", {
function: fn.id,
event: ctx.event.name
});
},
afterExecution() {
const duration = Date.now() - startTime;
metrics.histogram("inngest.step.duration", duration, {
function: fn.id,
event: ctx.event.name
});
},
transformOutput({ result }) {
const status = result.error ? "error" : "success";
metrics.increment("inngest.step.completed", {
function: fn.id,
status: status
});
return { result };
}
};
}
};
}
});typescript
const metricsMiddleware = new InngestMiddleware({
name: "Metrics Tracking",
init() {
return {
onFunctionRun({ ctx, fn }) {
let startTime: number;
return {
beforeExecution() {
startTime = Date.now();
metrics.increment("inngest.step.started", {
function: fn.id,
event: ctx.event.name
});
},
afterExecution() {
const duration = Date.now() - startTime;
metrics.histogram("inngest.step.duration", duration, {
function: fn.id,
event: ctx.event.name
});
},
transformOutput({ result }) {
const status = result.error ? "error" : "success";
metrics.increment("inngest.step.completed", {
function: fn.id,
status: status
});
return { result };
}
};
}
};
}
});Advanced Patterns
高级模式
Authentication: Validate tokens and inject user context
Conditional logic: Apply middleware based on event type or function
Circuit breakers: Prevent cascading failures from external services
身份验证: 验证令牌并注入用户上下文
条件逻辑: 根据事件类型或函数应用中间件
断路器: 防止外部服务故障引发级联失败
Configuration-Based Middleware
基于配置的中间件
Create reusable middleware with configuration options for different environments and use cases. See reference documentation for complete examples.
创建可复用的中间件,为不同环境和使用场景提供配置选项。完整示例请参阅参考文档。
Best Practices
最佳实践
Design Principles
设计原则
- Keep middleware focused: One concern per middleware
- Handle errors gracefully: Don't let middleware crash functions
- Consider performance: Middleware runs on every execution
- Use proper typing: Let TypeScript infer middleware types
- Test thoroughly: Middleware affects all functions that use it
- 保持中间件聚焦: 每个中间件只处理一个关注点
- 优雅处理错误: 不要让中间件导致函数崩溃
- 考虑性能: 中间件会在每次执行时运行
- 使用正确的类型: 让TypeScript自动推断中间件类型
- 充分测试: 中间件会影响所有使用它的函数
Common Use Cases to Implement
推荐实现的常见场景
- Retry logic for transient failures
- Circuit breakers for external service calls
- Request/response logging for debugging
- User context enrichment from external sources
- Feature flags for gradual rollouts
- Custom authentication and authorization checks
- 重试逻辑 处理临时故障
- 断路器 用于外部服务调用
- 请求/响应日志 用于调试
- 用户上下文 enrichment 从外部源获取
- 功能标志 用于逐步发布
- 自定义身份验证 和授权检查
Error Handling in Middleware
中间件中的错误处理
typescript
const robustMiddleware = new InngestMiddleware({
name: "Robust Middleware",
init() {
return {
onFunctionRun({ ctx, fn }) {
return {
transformOutput({ result }) {
try {
// Your middleware logic here
return performTransformation(result);
} catch (middlewareError) {
// Log error but don't break the function
console.error("Middleware error:", middlewareError);
// Return original result on middleware failure
return { result };
}
}
};
}
};
}
});typescript
const robustMiddleware = new InngestMiddleware({
name: "Robust Middleware",
init() {
return {
onFunctionRun({ ctx, fn }) {
return {
transformOutput({ result }) {
try {
// 你的中间件逻辑在这里
return performTransformation(result);
} catch (middlewareError) {
// 记录错误但不中断函数
console.error("中间件错误:", middlewareError);
// 中间件失败时返回原始结果
return { result };
}
}
};
}
};
}
});Testing Middleware
测试中间件
Use Inngest's testing utilities (, ) to unit test middleware behavior.
createMockContextcreateMockFunctionFor complete implementation examples and advanced patterns, see:
- Dependency Injection Reference
- Built-in Middleware Reference
使用Inngest的测试工具(、)对中间件行为进行单元测试。
createMockContextcreateMockFunction完整的实现示例和高级模式,请参阅:
- Dependency Injection Reference
- Built-in Middleware Reference