Middleware lifecycle v2.0.0+
Registering and order
Middleware can be registered with Inngest clients or functions by providing an array of middleware.
// Adding middleware to a client
const inngest = new Inngest({
id: "my-app",
middleware: [errorHandlerMiddleware, loggingMiddleware],
});
// Adding middleware to a function
inngest.createFunction(
{ id: "example", middleware: [dbConnectionMiddleware] },
{ event: "test" },
async () => {
// ...
}
);
Adding middleware contributes to an overall "stack" of middleware. If you register multiple middlewares, the SDK will group and run hooks for each middleware in the following order:
- Middleware registered on the client, in descending order
- Middleware registered on the function, in descending order
For example:
const inngest = new Inngest({
id: "my-app",
middleware: [
logMiddleware, // This is executed first
errorMiddleware, // This is executed second
],
});
inngest.createFunction(
{
id: "example",
middleware: [
dbSetupMiddleware, // This is executed third
datadogMiddleware, // This is executed fourth
],
},
{ event: "test" },
async () => {
// ...
}
);
Hook reference
The init()
function can return functions for two separate lifecycles to hook into.
💡 All lifecycle and hook functions can be synchronous or async
functions - the SDK will always wait until a middleware's function has resolved before continuing to the next one.
onFunctionRun
lifecycle
Triggered when a function is going to be executed.
- Name
ctx
- Type
- object
- Required
- optional
- Description
The input data for the function. Only
event
andrunId
are available at this point.
- Name
steps
- Type
- array
- Required
- optional
- Description
An array of previously-completed step objects.
- Name
fn
- Type
- InngestFunction
- Required
- optional
- Description
The function that is about to be executed.
- Name
reqArgs
- Type
- array
- Required
- optional
- Version
- Description
Arguments passed to the framework's request handler, which are used by the SDK's
serve
handler.
v3.9.0+
- Name
transformInput
- Type
- function
- Required
- optional
- Description
Called once the input for the function has been set up. This is where you can modify the input before the function starts.
Has the same input as the containing
onFunctionRun()
lifecycle function, but with a completectx
object, includingstep
tooling.
- Name
beforeMemoization
- Type
- function
- Required
- optional
- Description
Called before the function starts to memoize state (running over previously-seen code).
- Name
afterMemoization
- Type
- function
- Required
- optional
- Description
Called after the function has finished memoizing state (running over previously-seen code).
- Name
beforeExecution
- Type
- function
- Required
- optional
- Description
Called before the function starts to execute (running code seen for the first time).
- Name
afterExecution
- Type
- function
- Required
- optional
- Description
Called after the function has finished executing.
- Name
transformOutput
- Type
- function
- Required
- optional
- Description
Called after the function has finished executing and before the response is sent back to Inngest. This is where you can modify the output.
- Name
finished
- Type
- function
- Required
- optional
- Version
- Description
Called when execution is complete and a final response is returned (success or an error), which will end the run.
This function is not guaranteed to be called on every execution. It may be called multiple times if there are many parallel executions or during retries.
v3.21.0+- Name
beforeResponse
- Type
- function
- Required
- optional
- Description
Called after the output has been set and before the response has been sent back to Inngest. Use this to perform any final actions before the request closes.
const myMiddleware = new InngestMiddleware({
name: "My Middleware",
init({ client, fn }) {
return {
onFunctionRun({ ctx, fn, steps }) {
return {
transformInput({ ctx, fn, steps }) {
// ...
return {
// All returns are optional
ctx: { /* extend fn input */ },
steps: steps.map(({ data }) => { /* transform step data */ })
}
},
beforeMemoization() {
// ...
},
afterMemoization() {
// ...
},
beforeExecution() {
// ...
},
afterExecution() {
// ...
},
transformOutput({ result, step }) {
// ...
return {
// All returns are optional
result: {
// Transform data before it goes back to Inngest
data: transformData(result.data)
}
}
},
finished({ result }) {
// ...
},
beforeResponse() {
// ...
},
};
},
};
},
});
onSendEvent
lifecycle
Triggered when an event is going to be sent via inngest.send()
, step.sendEvent()
, or step.invoke()
.
- Name
transformInput
- Type
- function
- Required
- optional
- Description
Called before the events are sent to Inngest. This is where you can modify the events before they're sent.
- Name
transformOutput
- Type
- function
- Required
- optional
- Description
Called after events are sent to Inngest. This is where you can perform any final actions and modify the output from
inngest.send()
.
const myMiddleware = new InngestMiddleware({
name: "My Middleware",
init: ({ client, fn }) => {
return {
onSendEvent() {
return {
transformInput({ payloads }) {
// ...
},
transformOutput() {
// ...
},
};
},
};
},
});