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

推荐订阅源

GbyAI
GbyAI
Martin Fowler
Martin Fowler
I
InfoQ
腾讯CDC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
爱范儿
爱范儿
Microsoft Security Blog
Microsoft Security Blog
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
云风的 BLOG
云风的 BLOG
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
博客园 - 聂微东
Microsoft Azure Blog
Microsoft Azure Blog
D
Docker
博客园 - 三生石上(FineUI控件)
Y
Y Combinator Blog
博客园 - Franky
Engineering at Meta
Engineering at Meta
B
Blog
罗磊的独立博客
Apple Machine Learning Research
Apple Machine Learning Research
Jina AI
Jina AI
V
Visual Studio Blog

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 Fastify Hono Getting Started NestJS Next.js Nitro Nuxt Python SvelteKit Vite corrupted-event-log fetch-in-workflow hook-conflict Errors
defineHook
2026-05-31 · via Workflow SDK Documentation

Create type-safe hooks with consistent payload types and optional validation.

Creates a type-safe hook helper that ensures the payload type is consistent between hook creation and resumption.

This is a lightweight wrapper around createHook() and resumeHook() to avoid type mismatches. It also supports optional runtime validation and transformation of payloads using any Standard Schema v1 compliant validator like Zod or Valibot.

We recommend using defineHook() over createHook() in production codebases for better type safety and optional runtime validation.

import { defineHook } from "workflow";

const nameHook = defineHook<{
  name: string;
}>();

export async function nameWorkflow() {
  "use workflow";

  const hook = nameHook.create();  
  const result = await hook; // Fully typed as { name: string }
  console.log("Name:", result.name);
}

Parameters

NameTypeDescription
__0{ schema?: StandardSchemaV1<TInput, TOutput>; }Schema used to validate and transform the input payload before resuming

Returns

NameTypeDescription
create(options?: any) => Hook<T> Creates a new hook with the defined payload type.
resume(token: string, payload: T) => Promise<any> Resumes a hook by sending a payload with the defined type.

Basic Type-Safe Hook Definition

By defining the hook once with a specific payload type, you can reuse it in multiple workflows and API routes with automatic type safety.

import { defineHook } from "workflow";

// Define once with a specific payload type
const approvalHook = defineHook<{ 
  approved: boolean; 
  comment: string; 
}>(); 

// In your workflow
export async function workflowWithApproval() {
  "use workflow";

  const hook = approvalHook.create();
  const result = await hook; // Fully typed as { approved: boolean; comment: string }

  console.log("Approved:", result.approved);
  console.log("Comment:", result.comment);
}

Resuming with Type Safety

Hooks can be resumed using the same defined hook and a token. By using the same hook, you can ensure that the payload matches the defined type when resuming a hook.

// Use the same defined hook to resume
export async function POST(request: Request) {
  const { token, approved, comment } = await request.json();

  // Type-safe resumption - TypeScript ensures the payload matches
  const result = await approvalHook.resume(token, { 
    approved, 
    comment, 
  }); 

  if (!result) {
    return Response.json({ error: "Hook not found" }, { status: 404 });
  }

  return Response.json({ success: true, runId: result.runId });
}

Validate and Transform with Schema

You can provide runtime validation and transformation of hook payloads using the schema option. This option accepts any validator that conforms to the Standard Schema v1 specification.

Standard Schema is a standardized specification for schema validation libraries. Most popular validation libraries support it, including Zod, Valibot, ArkType, and Effect Schema. You can also write custom validators.

Using Zod with defineHook

Here's an example using Zod to validate and transform hook payloads:

import { defineHook } from "workflow";
import { z } from "zod";

export const approvalHook = defineHook({
  schema: z.object({ 
    approved: z.boolean(), 
    comment: z.string().min(1).transform((value) => value.trim()), 
  }), 
});

export async function approvalWorkflow(approvalId: string) {
  "use workflow";

  const hook = approvalHook.create({
    token: `approval:${approvalId}`,
  });

  // Payload is automatically typed based on the schema
  const { approved, comment } = await hook;
  console.log("Approved:", approved);
  console.log("Comment (trimmed):", comment);
}

When resuming the hook from an API route, the schema validates and transforms the incoming payload before the workflow resumes:

export async function POST(request: Request) {
  // Incoming payload: { token: "...", approved: true, comment: "   Ready!   " }
  const { token, approved, comment } = await request.json();

  // The schema validates and transforms the payload:
  // - Checks that `approved` is a boolean
  // - Checks that `comment` is a non-empty string
  // - Trims whitespace from the comment
  // If validation fails, an error is thrown and the hook is not resumed
  await approvalHook.resume(token, { 
    approved, 
    comment, // Automatically trimmed to "Ready!"
  }); 

  return Response.json({ success: true });
}

Using Other Standard Schema Libraries

The same pattern works with any Standard Schema v1 compliant library. Here's an example with Valibot:

import { defineHook } from "workflow";
import * as v from "valibot";

export const approvalHook = defineHook({
  schema: v.object({ 
    approved: v.boolean(), 
    comment: v.pipe(v.string(), v.minLength(1), v.trim()), 
  }), 
});

Customizing Tokens

Tokens are used to identify a specific hook and for resuming a hook. You can customize the token to be more specific to a use case.

import { defineHook } from "workflow";

const slackHook = defineHook<{ text: string; userId: string }>();

export async function slackBotWorkflow(channelId: string) {
  "use workflow";

  const hook = slackHook.create({
    token: `slack:${channelId}`, 
  });

  const message = await hook;
  console.log(`Message from ${message.userId}: ${message.text}`);
}