createAPIContext()function

createAPIContext(provider: APIProvider<P, R>): APIContext<P, R>
ParamType
providerAPIProvider<P, R>
APIProvider the created context resolves endpoint stores against. required
Return
APIContext<P, R>
APIContext bundle containing the useAPI() hook and the <APIContext> wrapper component.

Create an API context.

  • Allows React elements to call useAPI() to access endpoint stores in an API provider.
  • Each mounted APIContext gets its own in-memory store cache.

@todo Use and integreate our EndpointCache functionality and use it in this.

Create a React context for a Shelving shelving/api provider. Call createAPIContext(provider) once, outside any component, to produce an <APIContext> wrapper component and a useAPI hook. Each mounted <APIContext> gets its own in-memory APICache, so independent subtrees can use independent providers.

Usage

Wrap your tree in the context component and call useAPI(endpoint, payload) wherever you need data. useAPI returns an EndpointStore; read .value to get the response — the component suspends while loading and surfaces errors to the nearest error boundary.

tsx
import { Suspense } from "react";
import { ClientAPIProvider, ValidationAPIProvider, GET } from "shelving/api";
import { createAPIContext } from "shelving/react";
import { STRING, DATA } from "shelving/schema";

const UserSchema = DATA({ id: STRING, name: STRING });
const getUser = GET("/users/{id}", { id: STRING }, UserSchema);

const provider = new ValidationAPIProvider(new ClientAPIProvider({ url: "https://api.example.com" }));
const { APIContext, useAPI } = createAPIContext(provider);

function UserCard({ id }: { id: string }) {
  const store = useAPI(getUser, { id }); // Returns an EndpointStore; component suspends while loading.
  const user = store.value;
  return <div>{user.name}</div>;
}

function App() {
  return (
    <APIContext>
      <ErrorBoundary fallback={<p>Error</p>}>
        <Suspense fallback={<p>Loading...</p>}>
          <UserCard id="u_123" />
        </Suspense>
      </ErrorBoundary>
    </APIContext>
  );
}

useAPI accepts a nullish endpoint — passing undefined returns undefined instead of a store, which keeps the hook call unconditional. Calling useAPI outside an <APIContext> throws a RequiredError.

Examples

const { useAPI, APIContext } = createAPIContext(provider);