惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
The Hacker News
The Hacker News
V
Vulnerabilities – Threatpost
C
CXSECURITY Database RSS Feed - CXSecurity.com
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
AWS News Blog
AWS News Blog
S
Securelist
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
T
Troy Hunt's Blog
SecWiki News
SecWiki News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Security Latest
Security Latest
C
Cyber Attacks, Cyber Crime and Cyber Security
AI
AI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Stack Overflow Blog
Stack Overflow Blog
I
Intezer
I
InfoQ
Attack and Defense Labs
Attack and Defense Labs
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
The Exploit Database - CXSecurity.com
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
N
News | PayPal Newsroom
云风的 BLOG
云风的 BLOG
S
Secure Thoughts
T
The Blog of Author Tim Ferriss
Martin Fowler
Martin Fowler
L
LINUX DO - 最新话题
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
A
About on SuperTechFans
Hacker News - Newest:
Hacker News - Newest: "LLM"
TaoSecurity Blog
TaoSecurity Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Webroot Blog
Webroot Blog
L
LangChain Blog
MyScale Blog
MyScale Blog
Recent Announcements
Recent Announcements
P
Privacy & Cybersecurity Law Blog
Vercel News
Vercel News
Engineering at Meta
Engineering at Meta
C
Cybersecurity and Infrastructure Security Agency CISA
Y
Y Combinator Blog
L
Lohrmann on Cybersecurity
B
Blog RSS Feed
The Last Watchdog
The Last Watchdog

Workflow SDK Documentation

Patterns for Defining Tools Human-in-the-Loop Building Durable AI Agents Queueing User Messages Resumable Streams Sleep, Suspense, and Scheduling Streaming Updates from Tools API Reference Workflow Globals Changelog Resilient run start Cookbook Building a World Deploying Astro Express Hono Getting Started NestJS Next.js Nitro Nuxt Python SvelteKit Vite corrupted-event-log fetch-in-workflow hook-conflict Errors node-js-module-in-workflow serialization-failed start-invalid-workflow-function step-not-registered timeout-in-workflow webhook-invalid-respond-with-value webhook-response-not-sent workflow-not-registered Errors & Retrying Hooks & Webhooks Idempotency Foundations Serialization Starting Workflows Streaming Versioning Workflows and Steps How the Directives Work Encryption Event Sourcing Framework Integrations Understanding Directives Migration Guides Migrating from AWS Step Functions Migrating from Inngest Migrating from Temporal Observability Testing Server-Based Testing createHook createWebhook defineHook FatalError fetch getStepMetadata getWorkflowMetadata getWritable workflow RetryableError sleep @workflow/vitest DurableAgent @workflow/ai WorkflowChatTransport getHookByToken getRun getWorld workflow/api resumeHook resumeWebhook Chat Session Modeling runtime-decryption-failed Upgrading Workflows abort-signal-timeout-in-workflow Cancellation How Cancellation Works Internal Serializable AbortController and AbortSignal Eager Processing of Steps & Incremental Event Replay TanStack Start Agent Cancellation Sequential & Parallel Execution Workflow Composition Local World | Workflow SDK Postgres World | Workflow SDK Vercel World | Workflow SDK Migrating from trigger.dev Secure Credential Handling Local World | Workflow SDK Postgres World | Workflow SDK Vercel World | Workflow SDK
Fastify
2026-05-31 · via Workflow SDK Documentation

Set up your first durable workflow in a Fastify application.

This guide will walk through setting up your first workflow in a Fastify app. Along the way, you'll learn more about the concepts that are fundamental to using the Workflow SDK in your own projects.


Start by creating a new Fastify project.

Enter the newly made directory:

Initialize the project:

Install workflow, fastify and nitro

By default, Fastify doesn't include a build system. Nitro adds one which enables compiling workflows, runs, and deploys for development and production. Learn more about Nitro.

If using TypeScript, you need to install the @types/node and typescript packages

npm i -D @types/node typescript

Configure Nitro

Create a new file nitro.config.ts for your Nitro configuration with module workflow/nitro. This enables usage of the "use workflow" and "use step" directives

import { defineNitroConfig } from "nitro/config";

export default defineNitroConfig({
	modules: ["workflow/nitro"],
	vercel: { entryFormat: "node" },
	routes: {
		"/**": { handler: "./src/index.ts", format: "node" },
	},
});

Update package.json

To use the Nitro builder, update your package.json to include the following scripts:

{
  // ...
  "scripts": {
    "dev": "nitro dev",
    "build": "nitro build"
  },
  // ...
}

Create a new file for our first workflow:

import { sleep } from "workflow";

export async function handleUserSignup(email: string) {
  "use workflow"; 

  const user = await createUser(email);
  await sendWelcomeEmail(user);

  await sleep("5s"); // Pause for 5s - doesn't consume any resources
  await sendOnboardingEmail(user);

  return { userId: user.id, status: "onboarded" };
}

We'll fill in those functions next, but let's take a look at this code:

  • We define a workflow function with the directive "use workflow". Think of the workflow function as the orchestrator of individual steps.
  • The Workflow SDK's sleep function allows us to suspend execution of the workflow without using up any resources. A sleep can be a few seconds, hours, days, or even months long.

Let's now define those missing functions:

import { FatalError } from "workflow";

// Our workflow function defined earlier

async function createUser(email: string) {
  "use step"; 
  console.log(`Creating user with email: ${email}`);
  return { id: crypto.randomUUID(), email };
}

async function sendWelcomeEmail(user: { id: string; email: string }) {
  "use step"; 
  console.log(`Sending welcome email to user: ${user.id}`);
  if (Math.random() < 0.3) {
    // Steps retry on unhandled errors
    throw new Error("Retryable!");
  }
}

async function sendOnboardingEmail(user: { id: string; email: string }) {
  "use step"; 
  if (!user.email.includes("@")) {
    // FatalError skips retries
    throw new FatalError("Invalid Email");
  }
  console.log(`Sending onboarding email to user: ${user.id}`);
}

Taking a look at this code:

  • Business logic lives inside steps. When a step is invoked inside a workflow, it gets enqueued to run on a separate request while the workflow is suspended, just like sleep.
  • If a step throws an error, like in sendWelcomeEmail, the step will automatically be retried until it succeeds (or hits the step's max retry count).
  • Steps can throw a FatalError if an error is intentional and should not be retried.

We'll dive deeper into workflows, steps, and other ways to suspend or handle events in Foundations.

To invoke your new workflow, we'll create both the Fastify app and a new API route handler at src/index.ts with the following code:

import Fastify from "fastify";
import { start } from "workflow/api";
import { handleUserSignup } from "../workflows/user-signup.js";

const app = Fastify({ logger: true });
app.post("/api/signup", async (req, reply) => {
  const { email } = req.body as { email: string };
  await start(handleUserSignup, [email]);
  return reply.send({ message: "User signup workflow started" });
});

// Wait for Fastify to be ready before handling requests
await app.ready();


export default (req: any, res: any) => {
  app.server.emit("request", req, res);
};

This route handler creates a POST request endpoint at /api/signup that will trigger your workflow.

To start your development server, run the following command in your terminal in the Fastify root directory:

Once your development server is running, you can trigger your workflow by running this command in the terminal:

curl -X POST --json '{"email":"hello@example.com"}' http://localhost:3000/api/signup

Check the Fastify development server logs to see your workflow execute as well as the steps that are being processed.

Additionally, you can use the Workflow SDK CLI or Web UI to inspect your workflow runs and steps in detail.

npx workflow inspect runs # add '--web' for an interactive Web based UI

Workflow SDK Web UI


Workflow SDK apps currently work best when deployed to Vercel and needs no special configuration.

Enable Fluid compute before deploying. Workflow is designed to take advantage of Fluid compute for efficient suspension and resumption. Without Fluid compute enabled, each workflow resume incurs a separate function cold start, which can result in significantly higher costs.

Check the Deploying section to learn how your workflows can be deployed elsewhere.

start() says it received an invalid workflow function

If you see this error:

'start' received an invalid workflow function. Ensure the Workflow Development Kit is configured correctly and the function includes a 'use workflow' directive.

Check both of these first:

  1. The workflow function includes "use workflow".
  2. Your Nitro config includes the workflow/nitro module.

See start-invalid-workflow-function for full examples and fixes.