diff --git a/pages/docs/examples/index.mdx b/pages/docs/examples/index.mdx index a38d40958..b726f605a 100644 --- a/pages/docs/examples/index.mdx +++ b/pages/docs/examples/index.mdx @@ -51,3 +51,15 @@ Send all function failures to Datadog (or similar) for monitoring. + +## Middleware + + + + Access environment variables and other Cloudflare bindings within Inngest functions when using Workers or Hono. + + + diff --git a/pages/docs/examples/middleware/cloudflare-workers-environment-variables.mdx b/pages/docs/examples/middleware/cloudflare-workers-environment-variables.mdx new file mode 100644 index 000000000..66adaa9ce --- /dev/null +++ b/pages/docs/examples/middleware/cloudflare-workers-environment-variables.mdx @@ -0,0 +1,110 @@ +import { CodeGroup } from "src/shared/Docs/mdx"; + +# Cloudflare Workers environment variables and context + +Cloudflare Workers does not set environment variables a global object like Node.js does with `process.env`. Workers [binds environment variables](https://developers.cloudflare.com/workers/configuration/environment-variables/) to the worker's special `fetch` event handler thought a specific `env` argument. + +This means accessing environment variables within Inngest function handlers isn't possible without explicitly passing them through from the worker event handler to the Inngest function handler. + +We can accomplish this by use the [middleware](/docs/features/middleware) feature for Workers or when using [Hono](/docs/learn/serving-inngest-functions#framework-hono). + +## Creating middleware + +You can create middleware which extracts the `env` argument from the Workers `fetch` event handler arguments for either Workers or Hono: + +1. Use `onFunctionRun`'s `reqArgs` array to get the `env` object and, optionally, cast a type. +2. Return the `env` object within the special `ctx` object of `transformInput` lifecycle method. + + + +```ts {{ title: "Workers" }} +import { Inngest, InngestMiddleware } from 'inngest'; + +const bindings = new InngestMiddleware({ + name: 'Cloudflare Workers bindings', + init({ client, fn }) { + return { + onFunctionRun({ ctx, fn, steps, reqArgs }) { + return { + transformInput({ ctx, fn, steps }) { + // reqArgs is the array of arguments passed to the Worker's fetch event handler + // ex. fetch(request, env, ctx) + // We cast the argument to the global Env var that Wrangler generates: + const env = reqArgs[1] as Env; + return { + ctx: { + // Return the env object to the function handler's input args + env, + }, + }; + }, + }; + }, + }; + }, +}); + +// Include the middleware when creating the Inngest client +export const inngest = new Inngest({ + id: 'my-workers-app', + middleware: [bindings], +}); +``` + +```ts {{ title: "Hono" }} +import { Inngest, InngestMiddleware } from 'inngest'; +import { type Context } from 'hono'; + +type Bindings = { + MY_VAR: string; + DB_URL: string; + MY_BUCKET: R2Bucket; +}; + +const bindings = new InngestMiddleware({ + name: 'Hono bindings', + init({ client, fn }) { + return { + onFunctionRun({ ctx, fn, steps, reqArgs }) { + return { + transformInput({ ctx, fn, steps }) { + // reqArgs is the array of arguments passed to a Hono handler + // We cast the argument to the correct Hono Context type with our + // environment variable bindings + const [honoCtx] = reqArgs as [Context<{ Bindings: Bindings }>]; + return { + ctx: { + // Return the context's env object to the function handler's input args + env: honoCtx.env, + }, + }; + }, + }; + }, + }; + }, +}); + +// Include the middleware when creating the Inngest client +export const inngest = new Inngest({ + id: 'my-hono-app', + middleware: [bindings], +}); +``` + + + +Within your functions, you can now access the environment variables via the `env` object argument that you returned in `transformInput` above. Here's an example function: + +```ts +const myFn = inngest.createFunction( + { id: 'my-fn' }, + { event: 'demo/event.sent' }, + // The "env" argument returned in transformInput is passed through: + async ({ event, step, env }) => { + + // The env object will be typed as well: + console.log(env.MY_VAR); + } +); +``` \ No newline at end of file diff --git a/pages/docs/features/middleware/create.mdx b/pages/docs/features/middleware/create.mdx index b4282acd2..9f2d49ce1 100644 --- a/pages/docs/features/middleware/create.mdx +++ b/pages/docs/features/middleware/create.mdx @@ -5,9 +5,10 @@ import { RiMistFill, RiPlugLine, RiTerminalBoxLine, + RiKeyLine, } from "@remixicon/react"; -# Creating a middleware +# Creating middleware Creating middleware means defining the lifecycles and subsequent hooks in those lifecycles to run code in. Lifecycles are actions such as a function run or sending events, and individual hooks within those are where we run code, usually with a _before_ and _after_ step. @@ -39,7 +40,7 @@ Creating middleware means defining the lifecycles and subsequent hooks in those middleware: [myMiddleware], }); ``` - + @@ -340,7 +341,7 @@ It's common for middleware to require additional customization or options from d ## Next steps -Check out our pre-build middleware and examples: +Check out our pre-built middleware and examples: } href={'/docs/features/middleware/dependency-injection'}> @@ -355,6 +356,9 @@ Check out our pre-build middleware and examples: } href={'/docs/examples/track-failures-in-datadog'}> Add tracing with Datadog under a few minutes. + } href={'/docs/examples/middleware/cloudflare-workers-environment-variables'}> + Access environment variables within Inngest functions. + diff --git a/pages/docs/learn/serving-inngest-functions.mdx b/pages/docs/learn/serving-inngest-functions.mdx index 7100f84b2..fa4d87b59 100644 --- a/pages/docs/learn/serving-inngest-functions.mdx +++ b/pages/docs/learn/serving-inngest-functions.mdx @@ -1,4 +1,4 @@ -import { Callout, CodeGroup, VersionBadge, GuideSelector, GuideSection } from "shared/Docs/mdx"; +import { Callout, Tip, CodeGroup, VersionBadge, GuideSelector, GuideSection, Col, Row } from "shared/Docs/mdx"; export const description = `Serve the Inngest API as an HTTP endpoint in your application.` export const hidePageSidebar = true; @@ -32,13 +32,41 @@ serve({ }); ``` - - You will find the complete list of supported frameworks below. - - -## Supported Platforms - -Below you will find a list of framework-specific bindings, as well as instructions on adding bindings to [custom platforms](#custom-frameworks)! +## Supported frameworks and platforms + +
+ + +* [Astro](#framework-astro) +* [AWS Lambda](#framework-aws-lambda) +* [Bun](#bun-serve) +* [Cloudflare Pages](#framework-cloudflare-pages-functions) +* [Cloudflare Workers](#framework-cloudflare-workers) +* [DigitalOcean Functions](#framework-digital-ocean-functions) +* [Express](#framework-express) + + +* [Fastify](#framework-fastify) +* [Fresh (Deno)](#framework-fresh-deno) +* [Google Cloud Run Functions](#framework-google-cloud-run-functions) +* [Firebase Cloud functions](#framework-firebase-cloud-functions) +* [H3](#framework-h3) +* [Hono](#framework-hono) +* [Koa](#framework-koa) + + +* [NestJS](#framework-nest-js) +* [Next.js](#framework-next-js) +* [Nitro](#framework-nitro) +* [Nuxt](#framework-nuxt) +* [Redwood](#framework-redwood) +* [Remix](#framework-remix) +* [SvelteKit](#framework-svelte-kit) + + +
+ +You can also create a custom serve handler for any framework or platform not listed here - [read more here](#custom-frameworks). Want us to add support for another framework? Open an issue on [GitHub](https://github.com/inngest/website) or tell us about it on our [Discord](/discord). @@ -155,11 +183,17 @@ export default { fetch: serve({ client: inngest, functions: [fnA], + // We suggest explicitly defining the path to serve Inngest functions + servePath: "/api/inngest", }), }; ``` + + To automatically pass environment variables defined with Wrangler to Inngest function handlers, use the [Cloudflare Workers bindings middleware](/docs/examples/middleware/cloudflare-workers-environment-variables). + + When developing locally with Wrangler and the `--remote` flag, your code is deployed and run remotely. To use this with a local Inngest Dev Server, you must use a tool such as [ngrok](https://ngrok.com/) or @@ -488,7 +522,7 @@ See the [github.com/unjs/h3](https://github.com/unjs/h3) repository for more inf ### Framework: Hono -Add the following to `./src/index.ts`: +Inngest supports the [Hono](https://hono.dev/) framework which is popularly deployed to Cloudflare Workers. Add the following to `./src/index.ts`: ```ts @@ -511,6 +545,10 @@ export default app; ``` + + To automatically pass environment variables defined with Wrangler to Inngest function handlers, use the [Hono bindings middleware](/docs/examples/middleware/cloudflare-workers-environment-variables). + + See the [Hono example](https://github.com/inngest/inngest-js/blob/main/examples/framework-hono) for more information. ### Framework: Koa diff --git a/pages/docs/reference/middleware/examples.mdx b/pages/docs/reference/middleware/examples.mdx index 32905608e..925dfe688 100644 --- a/pages/docs/reference/middleware/examples.mdx +++ b/pages/docs/reference/middleware/examples.mdx @@ -1,4 +1,5 @@ -import { Callout, CodeGroup, Properties, Property, Row, Col, VersionBadge } from "src/shared/Docs/mdx"; +import { Callout, CodeGroup, Properties, Property, Row, Col, VersionBadge, Card, CardGroup } from "src/shared/Docs/mdx"; +import { RiKeyLine } from "@remixicon/react" # Example middleware @@ -8,6 +9,7 @@ The following examples show how you might use middleware in some real-world scen - [Common actions for every function](#common-actions-for-every-function) - [Logging](#logging) - [Prisma in function context](#prisma-in-function-context) +- [Cloudflare Workers & Hono environment variables](/docs/examples/middleware/cloudflare-workers-environment-variables) --- @@ -283,3 +285,10 @@ const prismaMiddleware = new InngestMiddleware({ Check out [Common actions for every function](/docs/reference/middleware/examples#common-actions-for-every-function) to see how this technique can be used to create steps for all of your unique logic. +## Other examples + + + } href={'/docs/examples/middleware/cloudflare-workers-environment-variables'}> + Access environment variables within Inngest functions. + + \ No newline at end of file diff --git a/shared/Docs/navigationStructure.ts b/shared/Docs/navigationStructure.ts index 94f1127eb..4425a0b7d 100644 --- a/shared/Docs/navigationStructure.ts +++ b/shared/Docs/navigationStructure.ts @@ -652,7 +652,7 @@ const sectionHome: (NavGroup | NavLink)[] = [ href: `/docs/features/middleware`, }, { - title: "Creating a middleware", + title: "Creating middleware", href: `/docs/features/middleware/create`, }, { @@ -864,6 +864,16 @@ const sectionExamples: NavGroup[] = [ }, ], }, + { + title: "Middleware", + defaultOpen: true, + links: [ + { + title: "Cloudflare Workers & Hono environment variables", + href: `/docs/examples/middleware/cloudflare-workers-environment-variables`, + }, + ], + }, ]; export const isNavGroup = (