An open API service indexing awesome lists of open source software.

https://github.com/aurbano/typesafe-fetch

Type-Safe version of fetch that uses OpenAPI TypeScript definitions to check API calls at compile type. This is really AWESOME if you call APIs from a JS frontend :fire:
https://github.com/aurbano/typesafe-fetch

Last synced: 5 months ago
JSON representation

Type-Safe version of fetch that uses OpenAPI TypeScript definitions to check API calls at compile type. This is really AWESOME if you call APIs from a JS frontend :fire:

Awesome Lists containing this project

README

          

# Better Alternatives

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:

* [orval](https://orval.dev/)
* [openapi-typescript](https://github.com/drwpow/openapi-typescript)

-------
-------

# Type-Safe Fetch

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.*

## Demo

> Using typesafe-fetch with the Petstore demo API in VS Code to see the compiler suggested completions.

[![Screen capture](https://media.giphy.com/media/M3HnoezzZ3s7ESdiFD/giphy.gif)](https://giphy.com/gifs/M3HnoezzZ3s7ESdiFD)
## Usage

Install:
```
npm install typesafe-fetch

yarn add typesafe-fetch
```

Setup:

```ts
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({
fetch: fetchFn,
});

// Make API calls :)
const res = safeFetch('/endpoint', {
query: {
sampleParam: 123,
},
});
```

### Using with multiple APIs

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`)

```ts
import { paths as SomeApiDefinition } from "./some-api";
import { paths as SomeOtherApiDefinition } from "./some-other-api";

const safeFetch = getSafeFetch({
fetch,
});
```

## Generating the API definitions

This library relies on the TS models generated by [OpenAPI-TypeScript](https://github.com/drwpow/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.

## Fetch function

The library is setup by calling `getSafeFetch()` with your `ApiDefinition` and an object containing an optional `baseUrl` and a mandatory `fetch` function.

This function has the following signature:

```ts
type FetchOptions = {
method: string;
body?: BodyInit;
headers?: HeadersInit;
}

export type FetchFunction = (url: string, options: FetchOptions) => Promise;
```

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).

### Using `fetch` as a fetch function

You can either use the browser's built-in `fetch` function, or any of the polyfills such as `node-fetch`, `cross-fetch`...

```ts
const fetchFn: FetchFunction = (url, { method, body, headers }) =>
fetch(url, { method, body, headers }).then(res => res.json());
```

### Using `axios` as a fetch function

You can either use the browser's built-in `fetch` function, or any of the polyfills such as `node-fetch`, `cross-fetch`...

```ts
const fetchFn: FetchFunction = (url, { method, body, headers }) =>
axios({
url,
method,
headers,
data: body,
}).then(res => res.data);
```