title |
---|
openapi-fetch Examples |
Authentication often requires some reactivity dependent on a token. Since this library is so low-level, there are myriad ways to handle it:
Here’s how it can be handled using Nano Stores, a tiny (334 b), universal signals store:
// src/lib/api/index.ts
import { atom, computed } from "nanostores";
import createClient from "openapi-fetch";
import type { paths } from "./api/v1";
export const authToken = atom<string | undefined>();
someAuthMethod().then((newToken) => authToken.set(newToken));
export const client = computed(authToken, (currentToken) =>
createClient<paths>({
headers: currentToken ? { Authorization: `Bearer ${currentToken}` } : {},
baseUrl: "https://myapi.dev/v1/",
}),
);
// src/some-other-file.ts
import { client } from "./lib/api";
const { GET, POST } = client.get();
GET("/some-authenticated-url", {
/* … */
});
You can also use proxies which are now supported in all modern browsers:
// src/lib/api/index.ts
import createClient from "openapi-fetch";
import type { paths } from "./api/v1";
let authToken: string | undefined = undefined;
someAuthMethod().then((newToken) => (authToken = newToken));
const baseClient = createClient<paths>({ baseUrl: "https://myapi.dev/v1/" });
export default new Proxy(baseClient, {
get(_, key: keyof typeof baseClient) {
const newClient = createClient<paths>({
headers: authToken ? { Authorization: `Bearer ${authToken}` } : {},
baseUrl: "https://myapi.dev/v1/",
});
return newClient[key];
},
});
// src/some-other-file.ts
import client from "./lib/api";
client.GET("/some-authenticated-url", {
/* … */
});
You can also use a getter:
// src/lib/api/index.ts
import createClient from "openapi-fetch";
import type { paths } from "./api/v1";
let authToken: string | undefined = undefined;
someAuthMethod().then((newToken) => (authToken = newToken));
export default createClient<paths>({
baseUrl: "https://myapi.dev/v1/",
headers: {
get Authorization() {
return authToken ? `Bearer ${authToken}` : undefined;
},
},
});
// src/some-other-file.ts
import client from "./lib/api";
client.GET("/some-authenticated-url", {
/* … */
});
openapi-fetch is simple vanilla JS that can be used in any project. But sometimes the implementation in a framework may come with some prior art that helps you get the most out of your usage.
React Query is a perfect wrapper for openapi-fetch in React. At only 13 kB, it provides clientside caching and request deduping across async React components without too much client weight in return. And its type inference preserves openapi-fetch types perfectly with minimal setup.
Next.js is the most popular SSR framework for React. While React Query is recommended for all clientside fetching with openapi-fetch (not SWR), this example shows how to take advantage of Next.js’s server-side fetching with built-in caching.
SvelteKit’s automatic type inference can easily pick up openapi-fetch’s types in both clientside fetching and Page Data fetching. And it doesn’t need any additional libraries to work. SvelteKit also advises to use their custom fetch in load functions. This can be achieved with fetch options.
Note: if you’re using Svelte without SvelteKit, the root example in src/routes/+page.svelte
doesn’t use any SvelteKit features and is generally-applicable to any setup.
TODO