This repo works perfectly fine and is mostly just TS definitios that can be used to create typed fetch functions. However, there are better libraries that do a lot more than that:
Given a path and a method, the TypeScript compiler will guarantee that you are passing the correct path and query parameters, and the correct body (and only if needed) + it will return the correct type for the response object!
Realised already how insanely awesome that is? The compiler will validate every aspect of the API request, including the response type - automatically!
Bonus: Tiny library (~1kb) with 0 dependencies.
Using typesafe-fetch with the Petstore demo API in VS Code to see the compiler suggested completions.
Install:
npm install typesafe-fetch
yarn add typesafe-fetch
Setup:
import getSafeFetch, { FetchFunction } from 'typesafe-fetch';
// See below how to generate the API definitions
import { paths as ApiDefinition } from "./petstore";
const fetchFn: FetchFunction = (url, { method, body, headers }) => {
// You can also use a global error handler by catching errors here
// Or insert any additional custom headers
// This is also where you can decide which fetch function to use, see
// below for examples using other libraries
return fetch(url, { method, body, headers }).then(res => res.json());
};
// Now set up using your existing OpenAPI definition
const safeFetch = getSafeFetch<ApiDefinition>({
fetch: fetchFn,
});
// Make API calls :)
const res = safeFetch('/endpoint', {
query: {
sampleParam: 123,
},
});
You can use union types to combine multiple APIs into one (assuming the endpoints are different and the base URL is the same, otherwise just use different instances of safeFetch
)
import { paths as SomeApiDefinition } from "./some-api";
import { paths as SomeOtherApiDefinition } from "./some-other-api";
const safeFetch = getSafeFetch<SomeApiDefinition & SomeOtherApiDefinition>({
fetch,
});
This library relies on the TS models generated by OpenAPI-TypeScript
For the simplest way to generate the models run:
npx openapi-typescript https://petstore.swagger.io/v2/swagger.json --output petstore.schema.ts
Check out their docs for more advanced use-cases.
The library is setup by calling getSafeFetch<ApiDefinition>()
with your ApiDefinition
and an object containing an optional baseUrl
and a mandatory fetch
function.
This function has the following signature:
type FetchOptions = {
method: string;
body?: BodyInit;
headers?: HeadersInit;
}
export type FetchFunction = (url: string, options: FetchOptions) => Promise<any>;
All you need is to pass a function that will send the request in any way, and return a Promise
with the return data (not a Response
object, you must extract it from there).
You can either use the browser's built-in fetch
function, or any of the polyfills such as node-fetch
, cross-fetch
...
const fetchFn: FetchFunction = (url, { method, body, headers }) =>
fetch(url, { method, body, headers }).then(res => res.json());
You can either use the browser's built-in fetch
function, or any of the polyfills such as node-fetch
, cross-fetch
...
const fetchFn: FetchFunction = (url, { method, body, headers }) =>
axios({
url,
method,
headers,
data: body,
}).then(res => res.data);