INTEGRITY Dokumentace

Context (ctx)

Context API poskytuje metody pro správu životního cyklu Workeru nebo Durable Object.

Kontext je zpřístupněn na následujících místech:

Mějte na paměti, že Context API je dostupné výhradně v bezstavových kontextech (stateless), tedy nikoli Durable Objects. Durable Objects ovšem mají jiný objekt, Durable Object State, který je k dispozici jako this.ctx uvnitř třídy Durable Object a poskytuje část stejné funkcionality jako Context API.

props

ctx.props poskytuje způsob, jak předat Workeru dodatečnou konfiguraci na základě kontextu, ve kterém byl vyvolán. Pokud je například váš Worker volán jiným Workerem, ctx.props může poskytnout informace o volajícím workeru.

Představte si například, že konfigurujete Worker s názvem "frontend-worker", který musí kvůli úpravě dokumentů komunikovat s dalším Workerem s názvem "doc-worker". Worker "frontend-worker" byste mohli nakonfigurovat s Service Binding například:

{
	"services": [
		{
			"binding": "DOC_SERVICE",
			"service": "doc-worker",
			"entrypoint": "DocServiceApi",
			"props": {
				"clientId": "frontend-worker",
				"permissions": [
					"read",
					"write"
				]
			}
		}
	]
}
[[services]]
binding = "DOC_SERVICE"
service = "doc-worker"
entrypoint = "DocServiceApi"

  [services.props]
  clientId = "frontend-worker"
  permissions = [ "read", "write" ]

Nyní může frontend-worker volat doc-worker pomocí kódu, jako je env.DOC_SERVICE.getDoc(id). Tím se vytvoří Vzdálené volání procedur voláním metody getDoc() třídy DocServiceApi, WorkerEntrypoint třída exportované doc-workerem.

Konfigurace obsahuje props hodnota. Jedná se o libovolnou hodnotu JSON. Když DOC_SERVICE binding se používá, DocServiceApi instance, která volání přijímá, bude mít přístup k props hodnotu jako this.ctx.props. Zde jsme nakonfigurovali props pro určení, že volání pochází z frontend-worker a že by mělo být povoleno číst a zapisovat dokumenty. Obsah props může být cokoli, co chcete.

Platforma Workers je navržena tak, aby zajistila, že ctx.props může nastavit pouze osoba, která má oprávnění upravovat a nasazovat worker, jemuž je určen. To znamená, že se můžete spolehnout na obsah ctx.props je autentický. Není potřeba používat tajné klíče ani kryptografické podpisy v ctx.props hodnota.

ctx.props lze také použít ke konfiguraci rozhraní RPC, které reprezentuje konkrétní resource, čímž vznikne „vlastní binding“. Můžeme si například nakonfigurovat Service Binding na náš „doc-worker“, který umožní přístup pouze ke konkrétnímu dokumentu:

{
	"services": [
		{
			"binding": "FOO_DOCUMENT",
			"service": "doc-worker",
			"entrypoint": "DocumentApi",
			"props": {
				"docId": "e366592caec1d88dff724f74136b58b5",
				"permissions": [
					"read",
					"write"
				]
			}
		}
	]
}
[[services]]
binding = "FOO_DOCUMENT"
service = "doc-worker"
entrypoint = "DocumentApi"

  [services.props]
  docId = "e366592caec1d88dff724f74136b58b5"
  permissions = [ "read", "write" ]

Zde jsme umístili docId vlastnost v ctx.props. DocumentApi třídu lze navrhnout tak, aby poskytovala API pro konkrétní dokument identifikovaný ctx.props.docId, a vynucování zadaných oprávnění.

exports

ctx.exports poskytuje automaticky nakonfigurované vazby typu „loopback“ pro všechny vaše exporty nejvyšší úrovně.

Například:

import { WorkerEntrypoint } from "cloudflare:workers";

export class Greeter extends WorkerEntrypoint {
	greet(name) {
		return `Hello, ${name}!`;
	}
}

export default {
	async fetch(request, env, ctx) {
		let greeting = await ctx.exports.Greeter.greet("World");
		return new Response(greeting);
	},
};

V tomto příkladu výchozí obslužná rutina fetch volá Greeter třídu přes RPC, podobně jako byste použili Service Binding. Není k tomu ale potřeba žádná externí konfigurace. ctx.exports se naplní automaticky z importů nejvyšší úrovně.

Zadání ctx.props při použití ctx.exports

Loopback Service Bindings v ctx.exports mají navíc jednu schopnost, kterou běžné Service Bindings nemají: volající může určit hodnotu ctx.props který by měl být doručen volanému.

import { WorkerEntrypoint } from "cloudflare:workers";

export class Greeter extends WorkerEntrypoint {
	greet(name) {
		return `${this.ctx.props.greeting}, ${name}!`;
	}
}

export default {
	async fetch(request, env, ctx) {
		// Make a custom greeter that uses the greeting "Welcome".
		let greeter = ctx.exports.Greeter({ props: { greeting: "Welcome" } });

		// Greet the world. Returns "Welcome, World!"
		let greeting = await greeter.greet("World");

		return new Response(greeting);
	},
};
import { WorkerEntrypoint } from "cloudflare:workers";

type Props = {
	greeting: string;
};

export class Greeter extends WorkerEntrypoint<Env, Props> {
	greet(name) {
		return `${this.ctx.props.greeting}, ${name}!`;
	}
}

export default {
	async fetch(request, env, ctx) {
		// Make a custom greeter that uses the greeting "Welcome".
		let greeter = ctx.exports.Greeter({ props: { greeting: "Welcome" } });

		// Greet the world. Returns "Welcome, World!"
		let greeting = await greeter.greet("World");

		return new Response(greeting);
	},
} satisfies ExportedHandler<Env>;

Dynamické zadávání props je v tomto případě povoleno, protože volající je stejný Worker, a lze tedy předpokládat, že je důvěryhodný a smí zadat libovolné props. Možnost přizpůsobit props se hodí zejména tehdy, když se výsledný binding má předat jinému Workeru přes RPC nebo použít v env z dynamicky načítaný worker.

Upozorňujeme, že props hodnoty zadané tímto způsobem mohou obsahovat libovolný typ, který lze "trvale" serializovat. Patří sem všechny základní strukturovaně klonovatelné datové typy. Zahrnuje také samotné Service Bindings: Service Binding můžete umístit do props jiného Service Binding.

Typy TypeScript pro ctx.exports a ctx.props

Pokud používáte TypeScript, měli byste použít wrangler types příkaz pro automatické generování typů pro váš projekt. Vygenerované typy zajistí, že ctx.exports má správný typ.

Při deklarování třídy vstupního bodu, která přijímá props, nezapomeňte jej deklarovat jako extends WorkerEntrypoint<Env, Props>, kde Props je typ ctx.props. Viz příklad výše.

tracing

ctx.tracing poskytuje přístup k API pro vlastní spany pro vytváření uživatelsky definovaných trace spanů. Jde o stejný objekt, který je dostupný přes import { tracing } from "cloudflare:workers".

Trasování musí být povoleno ve svém Workeru, aby se zaznamenávaly spany.

export default {
	async fetch(request, env, ctx) {
		return ctx.tracing.enterSpan("handleRequest", async (span) => {
			span.setAttribute("url.path", new URL(request.url).pathname);
			const data = await env.MY_KV.get("key");
			return new Response(data);
		});
	},
};

Úplné podrobnosti API najdete v Vlastní spany.

waitUntil

ctx.waitUntil() prodlužuje životnost vašeho Workeru, takže můžete provádět práci, aniž by blokovala vrácení odpovědi, a tato práce může pokračovat i po odeslání odpovědi. Přijímá Promise, jejichž provádění Workers runtime dokončí i poté, co Worker vrátí odpověď prostřednictvím svého obslužná rutina.

Použijte ctx.waitUntil() pro práci, která se spouští po odeslání odpovědi, například logování, analytiku nebo zápisy do cache, pokud se stihne dokončit během waitUntil() časový limit. Pokud klient stále přijímá odpověď, včetně streamovaného těla odpovědi, volání Workeru zůstává aktivní bez ctx.waitUntil(). Pokud odpověď závisí na dokončení práce, await práci před vrácením odpovědi, nebo odpověď streamovat postupně, jak práce probíhá.

waitUntil se běžně používá k:

Můžete zavolat waitUntil() vícekrát. Podobně jako Promise.allSettled, i když Promise předaný jedné waitUntil volání je odmítnuto, promises předané dalším waitUntil() volání budou dále pokračovat ve vykonávání.

Například:

export default {
	async fetch(request, env, ctx) {
		// Forward / proxy original request
		let res = await fetch(request);

		// Add custom header(s)
		res = new Response(res.body, res);
		res.headers.set("x-foo", "bar");

		// Cache the response
		// NOTE: Does NOT block / wait
		ctx.waitUntil(caches.default.put(request, res.clone()));

		// Done
		return res;
	},
};

passThroughOnException

passThroughOnException metoda umožňuje Workeru fail open, a předat požadavek na origin server, pokud Worker vyvolá neošetřenou výjimku. To se hodí, pokud Workery používáte jako vrstvu před existující službou: služba za Workerem pak může sama ošetřit neočekávané chybové stavy, které ve vašem Workeru nastanou.

export default {
	async fetch(request, env, ctx) {
		ctx.passThroughOnException();

		try {
			return await fetch(request);
		} catch (error) {
			console.error("Origin fetch failed", error);
			return new Response("Bad Gateway", { status: 502 });
		}
	},
};