Fetch: performing API requests or fetching data TypeScript only

The Inngest TypeScript SDK provides a step.fetch() API and a fetch() utility, enabling you to make requests to third-party APIs or fetch data in a durable way by offloading them to the Inngest Platform:

  • step.fetch() is a shorthand for making HTTP requests from within an Inngest function, and it also makes it easier to start parallel HTTP requests.
  • The fetch() utility can be passed to packages that accept a custom fetch implementation, such as axios.

Using Fetch offloads the HTTP request to the Inngest Platform

Using step.fetch()

You can use step.fetch() to make HTTP requests within an Inngest function.

step.fetch() offloads the HTTP request to the Inngest Platform, so your service does not need to be active and waiting for the response.

src/inngest/functions.ts

import { inngest } from "./client";

export const retrieveTextFile = inngest.createFunction(
  { id: "retrieveTextFile" },
  { event: "textFile/retrieve" },
  async ({ step }) => {
    // The fetching of the text file is offloaded to the Inngest Platform
    const response = await step.fetch(
      "https://example-files.online-convert.com/document/txt/example.txt"
    );

    // The Inngest function run is resumed when the HTTP request is complete
    await step.run("extract-text", async () => {
      const text = await response.text();
      const exampleOccurences = text.match(/example/g);
      return exampleOccurences?.length;
    });
  }
);

step.fetch() is useful:

  • In serverless environments, to offload long-running HTTP requests that might trigger timeouts.
  • As a shorthand for making HTTP requests within an Inngest function, making it easier to start parallel HTTP requests using Promise.all().
  • As a best practice to ensure that all HTTP requests are durable and can be inspected in the Inngest Platform or Dev Server.

step.fetch() observability

All step.fetch() calls are visible in your Inngest Traces, allowing you to monitor and debug your HTTP requests:

Inngest Traces showing a step.fetch() call

Using the fetch() utility

A Fetch API-compatible function is exported, allowing you to make any HTTP requests durable if they're called within an Inngest function.

For example, a MyProductApi class that relies on axios can take a fetch parameter:

TypeScript

import { fetch } from "inngest";

const api = new MyProductApi({ fetch });

// A call outside an Inngest function will fall back to the global fetch
await api.getProduct(1);

// A call from inside an Inngest function will be made durable and offloaded to the Inngest Platform
inngest.createFunction(
  { id: "my-fn" },
  { event: "product/activated" },
  async () => {
    await api.getProduct(1);
  },
);

Within steps

By default, using Inngest's fetch retains all the functionality of requests made outside of an endpoint, but ensures that those made from inside are durable.

import { fetch } from "inngest";

const api = new MyProductApi({ fetch });

// A call outside an Inngest function will fall back to the global fetch
await api.getProduct(1);

// A call from inside an Inngest function will be made durable
inngest.createFunction(
  { id: "my-fn" },
  { event: "product/activated" },
  async () => {
    await api.getProduct(1);
  },
);

However, the same fetch is also exported as step.fetch, allowing you to create your APIs isolated within the function instead:

inngest.createFunction(
  { id: "my-fn" },
  { event: "product/activated" },
  async ({ step }) => {
    const api = new MyProductApi({ fetch: step.fetch });

    await api.getProduct(1);
  },
);

Fallbacks

By default, it will gracefully fall back to the global fetch if called outside of an Inngest function, though you can also set a custom fallback using the config method:

import { fetch } from "inngest";

const api = new MyProductApi({
  fetch: fetch.config({ fallback: myCustomFetch }),
});

You can also disable the fallback entirely:

import { fetch } from "inngest";

const api = new MyProductApi({
  fetch: fetch.config({ fallback: undefined }),
});

How it works

Inngest's fetch function uses some of the basic building blocks of Inngest to allow seamless creation of optionally durable code. When it's called, it will:

  • Check the context in which it's running
  • If not in an Inngest function, optionally use the fallback; otherwise,
  • Report the request to Inngest
  • Inngest makes the request
  • Inngest continues the function with the Response received from your request

Critically, this means that your service does not have to be active for the duration of the call; we'll continue your function when we have a result, while also keeping it durable!