Skip to content

Commit

Permalink
docs(fetch): add guide for fetch client (orval-labs#1476)
Browse files Browse the repository at this point in the history
  • Loading branch information
soartec-lab authored Jun 22, 2024
1 parent e1711e5 commit 9d79bf4
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
5 changes: 5 additions & 0 deletions docs/src/manifests/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
"path": "/guides/basics",
"editUrl": "/guides/basics.md"
},
{
"title": "Fetch API",
"path": "/guides/fetch",
"editUrl": "/guides/fetch.md"
},
{
"title": "React query",
"path": "/guides/react-query",
Expand Down
114 changes: 114 additions & 0 deletions docs/src/pages/guides/fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
id: fetch
title: Fetch
---

<a href="https://developer.mozilla.org/en-US/docs/Web/API/fetch" target="_blank">The `fetch` API</a> has the advantage of reducing the bundle size of the application compared to using `Axios`. It can also act as an `http client` in server-side frameworks and edge computing runtimes such as `Cloudflare`, `Vercel Edge` and `Deno`.

You should have an `OpenAPI` specification and an `Orval` config where you define the mode as `fetch`.

#### Example with fetch

```ts
import { defineConfig } from 'orval';

export default defineConfig({
petstore: {
output: {
mode: 'tags-split',
target: 'app/gen/petstore.ts',
schemas: 'app/gen/models',
client: 'fetch',
baseUrl: 'http://localhost:3000',
mock: true,
},
input: {
target: './petstore.yaml',
},
},
});
```

Checkout the [orval config](../reference/configuration/full-example) reference to see all available options.
Like the following example from this <a href="https://github.com/anymaniax/orval/blob/master/samples/next-app-with-fetch/petstore.yaml" target="_blank">`OpenAPI` Specification</a>:

```ts
/**
* @summary List all pets
*/
export type listPetsResponse = {
data: Pets;
status: number;
};

export const getListPetsUrl = (params?: ListPetsParams) => {
const normalizedParams = new URLSearchParams();

Object.entries(params || {}).forEach(([key, value]) => {
if (value === null) {
normalizedParams.append(key, 'null');
} else if (value !== undefined) {
normalizedParams.append(key, value.toString());
}
});

return `http://localhost:3000/pets?${normalizedParams.toString()}`;
};

export const listPets = async (
params?: ListPetsParams,
options?: RequestInit,
): Promise<listPetsResponse> => {
const res = await fetch(getListPetsUrl(params), {
...options,
method: 'GET',
});
const data = await res.json();

return { status: res.status, data };
};
```

The `fetch` client will generate an implementation file with following per path in your `OpenAPI` Specification.

1. A response type for the `fetch` function
2. A Function to generate request URL including query parameters and path parameters
3. A function that call `fetch` API.

Checkout <a href="https://github.com/anymaniax/orval/blob/master/samples/next-app-with-fetch" target="_blank">here</a> the full example

#### Custom instance

You can add a custom `fetch` function to your config.

```ts
module.exports = {
petstore: {
output: {
...
override: {
mutator: {
path: './custom-fetch.ts',
name: 'customFetch',
},
},
}
...
},
};
```

And, you prepare like the <a href="https://github.com/anymaniax/orval/blob/master/samples/next-app-with-fetch/custom-fetch.ts" target="_blank">sample implementation</a>
Then, you can generate a `fetch` client that calls the `customFetch` function like bellow:

```ts
export const listPets = async (
params?: ListPetsParams,
options?: RequestInit,
): Promise<listPetsResponse> => {
return customFetch<Promise<listPetsResponse>>(getListPetsUrl(params), {
...options,
method: 'GET',
});
};
```

0 comments on commit 9d79bf4

Please sign in to comment.