Defining Functions
A function is a workflow definition that responds to events. Functions contain one or more steps that execute in sequence, with automatic memoization for durability.
Basic Function Definition
import { ironflow } from "@ironflow/node";
export const processOrder = ironflow.createFunction( { id: "process-order", triggers: [{ event: "order.placed" }], }, async ({ event, step }) => { // Event data is typed via generics or casting const { orderId } = event.data as { orderId: string };
const result = await step.run("validate", async () => { return await validateOrder(orderId); });
return { success: true, result }; },);import "github.com/sahina/ironflow/sdk/go/ironflow"
var ProcessOrder = ironflow.CreateFunction(ironflow.FunctionConfig{ ID: "process-order", Triggers: []ironflow.Trigger{{Event: "order.placed"}},}, func(ctx ironflow.Context) (any, error) { var data OrderEvent if err := ctx.Event.Data(&data); err != nil { return nil, err }
result, err := ironflow.Run(ctx, "validate", func() (bool, error) { return validateOrder(data.OrderID) })
return map[string]any{"success": result}, err})Configuration Options
Functions accept a configuration object to tune retry logic, timeouts, and concurrency. The concurrency.key field uses dot-notation paths starting from the event root (e.g. event.data.orgId).
ironflow.createFunction( { id: "my-function", triggers: [{ event: "my.event" }], mode: "push", // "push" (default) or "pull" timeout: 600_000, // 10 min (ms) retry: { maxAttempts: 3, initialDelayMs: 1000, backoffFactor: 2.0, }, concurrency: { limit: 10, key: "event.data.orgId", // Group limits by this field }, secrets: ["STRIPE_KEY"], // Inject secrets at runtime }, handler,);import "time"
ironflow.CreateFunction(ironflow.FunctionConfig{ ID: "my-function", Triggers: []ironflow.Trigger{{Event: "my.event"}}, Mode: "pull", Retry: &ironflow.RetryConfig{ MaxAttempts: 5, InitialDelay: time.Second, BackoffFactor: 2.0, }, Concurrency: &ironflow.ConcurrencyConfig{ Limit: 10, Key: "event.data.orgId", }, Secrets: []string{"STRIPE_KEY"},}, handler)Event Data Access
The event object in the context contains the triggering event’s payload and metadata.
import { z } from "zod";
// Define your event schema with Zodconst orderPlacedSchema = z.object({ orderId: z.string(), amount: z.number(),});
// Pass the schema in the config for type-safe event dataexport const myFn = ironflow.createFunction( { id: "my-fn", triggers: [{ event: "order.placed" }], schema: orderPlacedSchema, }, async ({ event, step }) => { // event.data is now type-safe: { orderId: string, amount: number } console.log(event.data.orderId);
// Access user-defined metadata attached when the event was emitted const traceId = event.metadata?.traceId as string | undefined; const source = event.metadata?.source as string | undefined; },);func(ctx ironflow.Context) (any, error) { var data MyData // Unmarshal JSON data into your struct if err := ctx.Event.Data(&data); err != nil { return nil, err }
// Access user-defined metadata attached when the event was emitted traceId, _ := ctx.Event.Metadata["traceId"].(string) source, _ := ctx.Event.Metadata["source"].(string)
return data.ID, nil}Secrets Injection
If your function requires sensitive API keys, declare them in the secrets array. Ironflow will resolve these from its encrypted vault and inject them into the handler context at runtime.
async ({ event, step, secrets }) => { const apiKey = secrets.get("STRIPE_KEY");};func(ctx ironflow.Context) (any, error) { apiKey := ctx.Secrets.Get("STRIPE_KEY") return apiKey, nil}What’s Next?
- Step Primitives — Learn about run, sleep, and waitForEvent
- Execution Modes — Push mode vs. Pull mode