INTEGRITY Dokumentace

Workers API

Tento návod podrobně popisuje Workflows API v rámci Cloudflare Workers, včetně metod, typů a příkladů použití.

WorkflowEntrypoint

WorkflowEntrypoint třída je základním prvkem definice Workflow. Workflow musí tuto třídu rozšířit a definovat run metodu s alespoň jedním step volání, aby byl považován za platný Workflow.

export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
	async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
		// Steps here
	}
}

spustit

run metoda může volitelně vrátit data, která jsou dostupná při dotazování na stav instance přes Workers API, REST API a v dashboardu Workflows. To se hodí, pokud váš Workflow počítá výsledek, vrací klíč k datům uloženým v objektovém úložišti nebo generuje nějaký identifikátor, se kterým musíte dále pracovat.

export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
	async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
		// Steps here
		let someComputedState = await step.do("my step", async () => {});

		// Optional: return state from our run() method
		return someComputedState;
	}
}

WorkflowEvent přijímá volitelný typ parametr typu ↗ který umožňuje zadat typ pro payload vlastnost v rámci WorkflowEvent.

Viz události a parametry dokumentaci s postupem, jak zpracovávat události v kódu vašeho Workflow.

Nakonec lze použít jakýkoli řídicí prvek jazyka JS (podmínky if, cykly, try...catch bloky, promise a další) lze použít ke správě kroků uvnitř run metoda.

WorkflowEvent

export type WorkflowCronSchedule = {
	/** Cron expression that triggered this event. */
	cron: string;
	/** Timestamp of the scheduled trigger, in milliseconds since the Unix epoch. */
	scheduledTime: number;
};

export type WorkflowEvent<T> = {
	payload: Readonly<T>;
	timestamp: Date;
	instanceId: string;
	workflowName: string;
	schedule?: WorkflowCronSchedule;
};

Viz události a parametry dokumentaci s postupem, jak zpracovávat události v kódu vašeho Workflow.

WorkflowStep

krok

Po ReadableStream<Uint8Array> objekt byl uložen v rámci kroku, neměl by být znovu použit; spolehněte se na nový stream, který krok vrátí. Bajty jsou zachovány z původního streamu, ale implementace se může lišit.

:::

export class MyWorkflow extends WorkflowEntrypoint {
	async run(_event, step) {
		const reportStream = await step.do("read report from R2", async () => {
			const object = await this.env.MY_BUCKET.get("reports/latest.csv");

			if (!object?.body) {
				throw new Error("Could not read reports/latest.csv from R2.");
			}

			return object.body;
		});

		const preview = await new Response(reportStream).text();
		return { preview };
	}
}
type Env = {
	MY_BUCKET: R2Bucket;
};

export class MyWorkflow extends WorkflowEntrypoint<Env> {
	async run(_event: WorkflowEvent<unknown>, step: WorkflowStep) {
		const reportStream = await step.do("read report from R2", async () => {
			const object = await this.env.MY_BUCKET.get("reports/latest.csv");

			if (!object?.body) {
				throw new Error("Could not read reports/latest.csv from R2.");
			}

			return object.body;
		});

		const preview = await new Response(reportStream).text();
		return { preview };
	}
}
export class MyWorkflow extends WorkflowEntrypoint {
	async run(event, step) {
		// Other steps in your Workflow
		let stripeEvent = await step.waitForEvent(
			"receive invoice paid webhook from Stripe",
			{ type: "stripe-webhook", timeout: "1 hour" },
		);
		// Rest of your Workflow
	}
}
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
	async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
		// Other steps in your Workflow
		let stripeEvent = await step.waitForEvent<IncomingStripeWebhook>(
			"receive invoice paid webhook from Stripe",
			{ type: "stripe-webhook", timeout: "1 hour" },
		);
		// Rest of your Workflow
	}
}

Projděte si dokumentaci k události a parametry kde zjistíte, jak odesílat události běžící instanci Workflow.

WorkflowStepConfig

export type WorkflowDynamicDelayContext = {
	ctx: WorkflowStepContext;
	error: Error;
};

export type WorkflowDelayFunction = (
	input: WorkflowDynamicDelayContext,
) => string | number | Promise<string | number>;

export type WorkflowStepConfig = {
	retries?: {
		limit: number;
		delay: string | number | WorkflowDelayFunction;
		backoff?: WorkflowBackoff;
	};
	timeout?: string | number;
};

Viz dokumentace o uspávání a opakování kde se dozvíte více o tom, jak se Workflows opakují.

Možnosti rollbacku

type WorkflowRollbackContext<T = unknown> = {
	ctx: WorkflowStepContext;
	error: Error;
	output: T | undefined;
};

type WorkflowRollbackHandler<T = unknown> = (
	ctx: WorkflowRollbackContext<T>,
) => Promise<void>;

type WorkflowStepRollbackConfig = Pick<
	WorkflowStepConfig,
	"retries" | "timeout"
>;

type WorkflowStepRollbackOptions<T = unknown> = {
	rollback: WorkflowRollbackHandler<T>;
	rollbackConfig?: WorkflowStepRollbackConfig;
};
export class BillingWorkflow extends WorkflowEntrypoint {
	async run(_event, step) {
		await step.do(
			"create charge",
			async () => {
				const charge = await createCharge();
				return { chargeId: charge.id };
			},
			{
				rollback: async ({ ctx, output, error }) => {
					const { chargeId } = output;
					await refundCharge(chargeId, {
						reason: `${ctx.step.name}: ${error.message}`,
					});
				},
				rollbackConfig: {
					retries: {
						limit: 3,
						delay: "30 seconds",
						backoff: "linear",
					},
					timeout: "5 minutes",
				},
			},
		);
	}
}
export class BillingWorkflow extends WorkflowEntrypoint<Env> {
	async run(_event: WorkflowEvent<unknown>, step: WorkflowStep) {
		await step.do(
			"create charge",
			async () => {
				const charge = await createCharge();
				return { chargeId: charge.id };
			},
			{
				rollback: async ({ ctx, output, error }) => {
					const { chargeId } = output as { chargeId: string };
					await refundCharge(chargeId, {
						reason: `${ctx.step.name}: ${error.message}`,
					});
				},
				rollbackConfig: {
					retries: {
						limit: 3,
						delay: "30 seconds",
						backoff: "linear",
					},
					timeout: "5 minutes",
				},
			},
		);
	}
}

WorkflowStepContext

export type WorkflowStepContext = {
	step: {
		name: string;
		count: number;
	};
	attempt: number;
	config: WorkflowStepConfig;
};

Viz dokumentace ke kontextu kroku pro příklady použití.

Limity kroků Workflow

Každý workflow na Workers Paid standardně podporuje 10,000 kroků. Tento limit můžete zvýšit až na 25,000 kroků nastavením steps v rámci limits vlastnost definice vašeho Workflow ve vaší konfiguraci Wrangler:

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "workflows": [
    {
      "name": "my-workflow",
      "binding": "MY_WORKFLOW",
      "class_name": "MyWorkflow",
      "limits": {
        "steps": 25000
      }
    }
  ]
}
[[workflows]]
name = "my-workflow"
binding = "MY_WORKFLOW"
class_name = "MyWorkflow"

[workflows.limits]
steps = 25_000

step.sleep se nezapočítává do limitu maximálního počtu kroků.

Upozorňujeme, že Workflows v plánu Workers Free mají limit 1,024 kroků. Více informací najdete v Limity Workflow s dalšími informacemi.

NonRetryableError

Volání Workflows z Workers

Workflows zpřístupňují API přímo ve vašich skriptech Workers prostřednictvím vazby koncept. Vazby vám umožňují bezpečně volat Workflow, aniž byste museli spravovat API klíče nebo klienty.

Na Workflow se můžete navázat definováním [[workflows]] vazbu v rámci konfigurace Wrangler.

Chcete-li například vytvořit binding pro Workflow s názvem workflows-starter a zpřístupnit jej na MY_WORKFLOW proměnnou do skriptu Workeru, museli byste nastavit následující pole v [[workflows]] definici vazby:

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "workflows-starter",
	"main": "src/index.ts",
	// Set this to today's date
	"compatibility_date": "2026-08-28",
	"workflows": [
		{
			// name of your workflow
			"name": "workflows-starter",
			// binding name env.MY_WORKFLOW
			"binding": "MY_WORKFLOW",
			// this is class that extends the Workflow class in src/index.ts
			"class_name": "MyWorkflow",
		},
	],
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "workflows-starter"
main = "src/index.ts"
# Set this to today's date
compatibility_date = "2026-08-28"

[[workflows]]
name = "workflows-starter"
binding = "MY_WORKFLOW"
class_name = "MyWorkflow"

Napojení z Pages

Workflows můžete navázat a spouštět z Pages Functions nasazením projektu Workers s definicí vašeho Workflow a následným voláním daného Workeru pomocí service bindings nebo standardní fetch() volání.

Navštivte dokumentaci k volání Workflows z Pages příklady.

Volání mezi skripty

Navázat se můžete i na Workflow definovaný v jiném skriptu Workers, než ve kterém je definice vašeho Workflow. Stačí uvést script_name klíč s názvem skriptu do [[workflows]] definici vazby v konfiguraci Wrangler.

Pokud je váš Workflow definován ve skriptu Workeru s názvem billing-worker, ale voláte ji ze svého web-api-worker skriptu vaše Konfigurační soubor Wrangler by vypadala následovně:

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "web-api-worker",
	"main": "src/index.ts",
	// Set this to today's date
	"compatibility_date": "2026-08-28",
	"workflows": [
		{
			// name of your workflow
			"name": "billing-workflow",
			// binding name env.MY_WORKFLOW
			"binding": "MY_WORKFLOW",
			// this is class that extends the Workflow class in src/index.ts
			"class_name": "MyWorkflow",
			// the script name where the Workflow is defined.
			// required if the Workflow is defined in another script.
			"script_name": "billing-worker",
		},
	],
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "web-api-worker"
main = "src/index.ts"
# Set this to today's date
compatibility_date = "2026-08-28"

[[workflows]]
name = "billing-workflow"
binding = "MY_WORKFLOW"
class_name = "MyWorkflow"
script_name = "billing-worker"

Pokud používáte TypeScript, spusťte wrangler types pokaždé, když upravíte konfigurační soubor Wrangler. Tím se vygenerují typy pro env objekt na základě vašich vazeb, stejně jako typy runtime.

Workflow

Workflow typ poskytuje metody pro vytváření instancí Workflow, kontrolu jejich stavu a správu běžících instancí přímo ze skriptu Workeru. Je součástí vygenerovaných typů, které vytváří wrangler types.

./worker-configuration.d.ts
interface Env {
	// The 'MY_WORKFLOW' variable should match the "binding" value set in the Wrangler config file
	MY_WORKFLOW: Workflow;
}

Workflow typ exportuje následující metody:

vytvořit

Vytvořte (spusťte) novou instanci daného Workflow.

ID se generuje automaticky, ale lze zadat i ID definované uživatelem (až 100 znaků 1). To se hodí například při mapování Workflows na uživatele, obchodníky nebo jiné identifikátory ve vašem systému. Můžete také zadat objekt JSON jako params vlastnost, která umožňuje předat data, se kterými bude instance Workflow pracovat jako se svým WorkflowEvent.

// Create a new Workflow instance with your own ID and pass params to the Workflow instance
let instance = await env.MY_WORKFLOW.create({
	id: myIdDefinedFromOtherSystem,
	params: { hello: "world" },
});
return Response.json({
	id: instance.id,
	details: await instance.status(),
});

Vrátí WorkflowInstance.

Vyvolá chybu, pokud je zadané ID již použito existující instancí, která ještě neprošla svým limit uchovávání. Chcete-li workflow se stejným ID spustit znovu, můžete restart existující instanci.

Parametr typu můžete zadat také do Workflows typ při vytváření (spouštění) instance Workflow pomocí create metoda v rámci Workers API. Upozorňujeme, že to ne přenášet informace o typech do samotného Workflow, protože typy TypeScript jsou konstrukcí, která existuje pouze v době sestavení.

Chcete-li zadat volitelný parametr typu pro Workflow, při definování bindings Workflow předejte jako argument typu svůj typ:

interface User {
	email: string;
	createdTimestamp: number;
}

interface Env {
	// Pass our User type as the type parameter to the Workflow definition
  MY_WORKFLOW: Workflow<User>;
}

export default {
	async fetch(request, env, ctx) {
		// More likely to come from your database or via the request body!
		const user: User = {
			email: [email protected],
			createdTimestamp: Date.now()
		}

		let instance = await env.MY_WORKFLOW.create({
			// params expects the type User
			params: user
		})

		return Response.json({
			id: instance.id,
			details: await instance.status(),
		});
	}
}

createBatch

Vytvořte (spusťte) dávku nových instancí daného Workflow, až 100 instancí najednou.

To se hodí, pokud plánujete více instancí najednou. Volání createBatch se zpracovává stejně jako volání create (pro jednu instanci) a umožňuje vám pracovat v rámci limit vytváření instancí.

Každý prvek batch se očekává, že tento seznam bude obsahovat jak id a params vlastnosti:

// Create a new batch of 3 Workflow instances, each with its own ID and pass params to the Workflow instances
const listOfInstances = [
	{ id: "id-abc123", params: { hello: "world-0" } },
	{ id: "id-def456", params: { hello: "world-1" } },
	{ id: "id-ghi789", params: { hello: "world-2" } },
];
let instances = await env.MY_WORKFLOW.createBatch(listOfInstances);

Vrátí pole WorkflowInstance.

Na rozdíl od create, tato operace je idempotentní a neselže, i když je dané ID již použito. Pokud se stávající instance se stejným ID stále nachází ve své limit uchovávání, bude přeskočen a vyřazen z vráceného pole.

získat

Získat konkrétní instanci Workflow podle ID.

Vrátí WorkflowInstance. Vyvolá výjimku, pokud instance s daným ID neexistuje.

// Fetch an existing Workflow instance by ID:
try {
	let instance = await env.MY_WORKFLOW.get(id);
	return Response.json({
		id: instance.id,
		details: await instance.status(),
	});
} catch (e: any) {
	// Handle errors
	// .get will throw an exception if the ID doesn't exist or is invalid.
	const msg = `failed to get instance ${id}: ${e.message}`;
	console.error(msg);
	return Response.json({ error: msg }, { status: 400 });
}

WorkflowInstanceCreateOptions

Volitelné vlastnosti, které lze předat při vytváření instance.

interface WorkflowInstanceCreateOptions {
	/**
	 * An id for your Workflow instance. Must be unique within the Workflow.
	 */
	id?: string;
	/**
	 * The event payload the Workflow instance is triggered with
	 */
	params?: unknown;
	/**
	 * The retention policy for the Workflow instance.
	 * Defaults to the maximum retention period available for the owner's account.
	 */
	retention?: {
		/**
		 * How long to retain instance state after the Workflow completes successfully.
		 */
		successRetention?: WorkflowRetentionDuration;
		/**
		 * How long to retain instance state after the Workflow ends in an errored or terminated state.
		 */
		errorRetention?: WorkflowRetentionDuration;
	};
}

type WorkflowRetentionDuration = WorkflowSleepDuration;

Pokud retention není nastaveno, stav instance se uchovává po maximální dobu uchování dostupnou pro váš účet (3 dny v plánu Workers Free, 30 dní v plánu Workers Paid). Podrobnosti najdete v limit uchovávání s dalšími informacemi.

Následující příklad vytvoří instanci, která si stav uchová 1 den po úspěchu a 7 dní po chybě:

let instance = await env.MY_WORKFLOW.create({
	id: myIdDefinedFromOtherSystem,
	params: { hello: "world" },
	retention: {
		successRetention: "1 day",
		errorRetention: "7 days",
	},
});

WorkflowInstance

Představuje konkrétní instanci Workflow a poskytuje metody pro správu této instance.

declare abstract class WorkflowInstance {
	public id: string;
	/**
	 * Pause the instance.
	 */
	public pause(): Promise<void>;
	/**
	 * Resume the instance. If it is already running, an error will be thrown.
	 */
	public resume(): Promise<void>;
	/**
	 * Terminate the instance. If it is errored, terminated or complete, an error will be thrown.
	 */
	public terminate(options?: WorkflowInstanceTerminateOptions): Promise<void>;
	/**
	 * Restart the instance from the beginning, or from a specific step.
	 */
	public restart(options?: WorkflowInstanceRestartOptions): Promise<void>;
	/**
	 * Returns the current status of the instance.
	 */
	public status(): Promise<InstanceStatus>;
}

id

Vrátí id Workflow.

stav

Vrátí stav běžící instance Workflow.

pozastavit

Pozastavte spuštěnou instanci Workflow.

obnovit

Obnovte pozastavenou instanci Workflow.

restartovat

Restartujte instanci Workflow od začátku nebo od konkrétního kroku.

let instance = await env.MY_WORKFLOW.get("abc-123");

// Restart the instance from the beginning.
await instance.restart();

// Restart the instance from the step named "aggregate".
await instance.restart({ from: { name: "aggregate" } });

// Restart the instance from the third call to a step named "process".
await instance.restart({ from: { name: "process", count: 3 } });

Při restartu od konkrétního kroku se znovu použijí uložené výsledky všech předchozích kroků, zatímco cílový krok a všechny kroky po něm se spustí znovu. Volání vyvolá chybu, pokud žádný krok neodpovídá from se nachází v historii spouštění instance.

WorkflowInstanceRestartOptions

interface WorkflowInstanceRestartOptions {
	/**
	 * The step to restart the instance from.
	 * If omitted, the instance restarts from the beginning.
	 */
	from?: {
		/**
		 * The name of the step.
		 */
		name: string;
		/**
		 * The 1-based index of the step, used when multiple steps share the same name and type. Defaults to 1 (the first occurrence).
		 */
		count?: number;
		/**
		 * The step type. Use this to disambiguate when the same name is shared across step types. Defaults to "do".
		 */
		type?: "do" | "sleep" | "waitForEvent";
	};
}

from objekt určuje krok, od kterého se má restart provést. Pouze name je povinné; count a type jsou potřeba pouze v případě, že se stejný název kroku v rámci běhu vyskytuje vícekrát.

ukončit

Ukončí instanci Workflow.

let instance = await env.MY_WORKFLOW.get("abc-123");

// Terminate without running rollback handlers.
await instance.terminate();

// Run registered rollback handlers before terminating.
await instance.terminate({ rollback: true });

Pokud rollback je true, Workflows spustí rollback handlery zaregistrované dokončenými nebo způsobilými kroky, než instance dosáhne stavu terminated stavu. Kroky bez obslužných rutin pro rollback se přeskočí.

WorkflowInstanceTerminateOptions

interface WorkflowInstanceTerminateOptions {
	/**
	 * If true, run registered rollback handlers before terminating the instance.
	 */
	rollback?: boolean;
}

sendEvent

Odeslání události běžící instanci Workflow.

Vraťte void při úspěchu; pokud Workflow neběží nebo je v chybovém stavu, vyvolá výjimku.

export default {
	async fetch(req, env) {
		const instanceId = new URL(req.url).searchParams.get("instanceId");
		const webhookPayload = await req.json();

		let instance = await env.MY_WORKFLOW.get(instanceId);
		// Send our event, with `type` matching the event type defined in
		// our step.waitForEvent call
		await instance.sendEvent({
			type: "stripe-webhook",
			payload: webhookPayload,
		});

		return Response.json({
			status: await instance.status(),
		});
	},
};
export default {
	async fetch(req: Request, env: Env) {
		const instanceId = new URL(req.url).searchParams.get("instanceId");
		const webhookPayload = await req.json<Payload>();

		let instance = await env.MY_WORKFLOW.get(instanceId);
		// Send our event, with `type` matching the event type defined in
		// our step.waitForEvent call
		await instance.sendEvent({
			type: "stripe-webhook",
			payload: webhookPayload,
		});

		return Response.json({
			status: await instance.status(),
		});
	},
};

Můžete zavolat sendEvent vícekrát a nastavíte hodnotu type vlastnost, aby odpovídala konkrétní waitForEvent volání ve vašem Workflow.

Díky tomu můžete čekat na více událostí najednou nebo použít Promise.race k čekání na více událostí, přičemž Workflow pokračuje hned po přijetí první z nich.

InstanceStatus

Popisuje stav instance Workflow.

type InstanceStatus = {
	status:
		| "queued" // means that instance is waiting to be started (see concurrency limits)
		| "running"
		| "paused"
		| "errored"
		| "terminated" // user terminated the instance while it was running
		| "complete"
		| "waiting" // instance is hibernating and waiting for sleep or event to finish
		| "waitingForPause" // instance is finishing the current work to pause
		| "unknown";
	error?: {
		name: string;
		message: string;
	};
	output?: unknown;
	rollback: {
		outcome: "complete" | "failed";
		error: {
			name: string;
			message: string;
		} | null;
	} | null;
};

Pokud Workflow přejde do rollbacku, Workers API nadále hlásí status: "running" pro kompatibilitu, dokud probíhá rollback. Jakmile instance dosáhne koncového stavu, zkontrolujte rollback pro zjištění, zda kompenzační kroky proběhly úspěšně, nebo selhaly.

Poznámky pod čarou

  1. Vzor pro shodu: ^[a-zA-Z0-9_][a-zA-Z0-9-_]*$ ↩ ↩2 ↩3