Skip to content

Commit

Permalink
Merge pull request #1717 from kerwanp/main
Browse files Browse the repository at this point in the history
openapi-react-query
  • Loading branch information
kerwanp authored Jul 30, 2024
2 parents 4215f50 + 28f687f commit e9a6325
Show file tree
Hide file tree
Showing 32 changed files with 3,504 additions and 14 deletions.
7 changes: 7 additions & 0 deletions .changeset/friendly-moons-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"openapi-fetch": patch
"openapi-typescript": patch
"openapi-typescript-helpers": patch
---

Ignore configuration files in published package
5 changes: 5 additions & 0 deletions .changeset/strange-emus-clap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"openapi-fetch": patch
---

Create own client type for easier reusability
5 changes: 5 additions & 0 deletions .changeset/twelve-games-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"openapi-react-query": patch
---

Initial release
10 changes: 10 additions & 0 deletions docs/.vitepress/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ export const en = defineConfig({
{ text: "About", link: "/openapi-fetch/about" },
],
},
{
text: "openapi-react-query",
items: [
{ text: "Getting Started", link: "/openapi-react-query/" },
{ text: "useQuery", link: "/openapi-react-query/use-query" },
{ text: "useMutation", link: "/openapi-react-query/use-mutation" },
{ text: "useSuspenseQuery", link: "/openapi-react-query/use-suspense-query" },
{ text: "About", link: "/openapi-react-query/about" },
],
},
],
},
search: {
Expand Down
2 changes: 1 addition & 1 deletion docs/data/contributors.json

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions docs/openapi-react-query/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: About openapi-react-query
description: openapi-react-query Project Goals and contributors
---
<script setup>
import { VPTeamMembers } from 'vitepress/theme';
import contributors from '../data/contributors.json';
</script>

# About

## Project Goals

1. Types should be strict and inferred automatically from OpenAPI schemas with the absolute minimum number of generics needed.
2. Respect the original `@tanstack/react-query` APIs while reducing boilerplate.
3. Be as light and performant as possible.

## Contributors

This library wouldn’t be possible without all these amazing contributors:

<VPTeamMembers size="small" :members="contributors['openapi-react-query']" />

110 changes: 110 additions & 0 deletions docs/openapi-react-query/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
title: openapi-react-query
---
# Introduction

openapi-react-query is a type-safe tiny wrapper (1 kb) around [@tanstack/react-query](https://tanstack.com/query/latest/docs/framework/react/overview) to work with OpenAPI schema.

It works by using [openapi-fetch](../openapi-fetch/) and [openapi-typescript](../introduction) so you get all the following features:

- ✅ No typos in URLs or params.
- ✅ All parameters, request bodies, and responses are type-checked and 100% match your schema
- ✅ No manual typing of your API
- ✅ Eliminates `any` types that hide bugs
- ✅ Also eliminates `as` type overrides that can also hide bugs

::: code-group

```tsx [src/my-component.ts]
import createFetchClient from "openapi-fetch";
import createClient from "openapi-react-query";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript

const fetchClient = createFetchClient<paths>({
baseUrl: "https://myapi.dev/v1/",
});
const $api = createClient(fetchClient);

const MyComponent = () => {
const { data, error, isLoading } = $api.useQuery(
"get",
"/blogposts/{post_id}",
{
params: {
path: { post_id: 5 },
},
},
);

if (isLoading || !data) return "Loading...";

if (error) return `An error occured: ${error.message}`;

return <div>{data.title}</div>;
};
```

:::

## Setup

Install this library along with [openapi-fetch](../openapi-fetch/) and [openapi-typescript](../introduction):

```bash
npm i openapi-react-query openapi-fetch
npm i -D openapi-typescript typescript
```

::: tip Highly recommended

Enable [noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess) in your `tsconfig.json` ([docs](/advanced#enable-nouncheckedindexaccess-in-your-tsconfigjson))

:::

Next, generate TypeScript types from your OpenAPI schema using openapi-typescript:

```bash
npx openapi-typescript ./path/to/api/v1.yaml -o ./src/lib/api/v1.d.ts
```

## Basic usage

Once your types has been generated from your schema, you can create a [fetch client](../introduction.md), a react-query client and start querying your API.

::: code-group

```tsx [src/my-component.ts]
import createFetchClient from "openapi-fetch";
import createClient from "openapi-react-query";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript

const fetchClient = createFetchClient<paths>({
baseUrl: "https://myapi.dev/v1/",
});
const $api = createClient(fetchClient);

const MyComponent = () => {
const { data, error, isLoading } = $api.useQuery(
"get",
"/blogposts/{post_id}",
{
params: {
path: { post_id: 5 },
},
},
);

if (isLoading || !data) return "Loading...";

if (error) return `An error occured: ${error.message}`;

return <div>{data.title}</div>;
};
```

:::

::: tip
You can find more information about `createFetchClient` on the [openapi-fetch documentation](../openapi-fetch/index.md).
:::

65 changes: 65 additions & 0 deletions docs/openapi-react-query/use-mutation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
title: useMutation
---
# {{ $frontmatter.title }}

The `useMutation` method allows you to use the original [useMutation](https://tanstack.com/query/latest/docs/framework/react/guides/mutations).

- The result is the same as the original function.
- The `mutationKey` is `[method, path]`.
- `data` and `error` are fully typed.

::: tip
You can find more information about `useMutation` on the [@tanstack/react-query documentation](https://tanstack.com/query/latest/docs/framework/react/guides/mutations).
:::

## Example

::: code-group

```tsx [src/app.tsx]
import { $api } from "./api";

export const App = () => {
const { mutate } = $api.useMutation("patch", "/users");

return (
<button onClick={() => mutate({ body: { firstname: "John" } })}>
Update
</button>
);
};
```

```ts [src/api.ts]
import createFetchClient from "openapi-fetch";
import createClient from "openapi-react-query";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript

const fetchClient = createFetchClient<paths>({
baseUrl: "https://myapi.dev/v1/",
});
export const $api = createClient(fetchClient);
```

:::

## Api

```tsx
const query = $api.useQuery(method, path, options, queryOptions);
```

**Arguments**

- `method` **(required)**
- The HTTP method to use for the request.
- The method is used as key. See [Query Keys](https://tanstack.com/query/latest/docs/framework/react/guides/query-keys) for more information.
- `path` **(required)**
- The pathname to use for the request.
- Must be an available path for the given method in your schema.
- The pathname is used as key. See [Query Keys](https://tanstack.com/query/latest/docs/framework/react/guides/query-keys) for more information.
- `queryOptions`
- The original `useMutation` options.
- [See more information](https://tanstack.com/query/latest/docs/framework/react/reference/useMutation)

73 changes: 73 additions & 0 deletions docs/openapi-react-query/use-query.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
title: useQuery
---
# {{ $frontmatter.title }}

The `useQuery` method allows you to use the original [useQuery](https://tanstack.com/query/latest/docs/framework/react/guides/queries).

- The result is the same as the original function.
- The `functionKey` is `[method, path, params]`.
- `data` and `error` are fully typed.
- You can pass queries options as fourth parameter.

::: tip
You can find more information about `useQuery` on the [@tanstack/react-query documentation](https://tanstack.com/query/latest/docs/framework/react/guides/queries).
:::

## Example

::: code-group

```tsx [src/app.tsx]
import { $api } from "./api";

export const App = () => {
const { data, error, isLoading } = $api.useQuery("get", "/users/{user_id}", {
params: {
path: { user_id: 5 },
},
});

if (!data || isLoading) return "Loading...";
if (error) return `An error occured: ${error.message}`;

return <div>{data.firstname}</div>;
};
```

```ts [src/api.ts]
import createFetchClient from "openapi-fetch";
import createClient from "openapi-react-query";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript

const fetchClient = createFetchClient<paths>({
baseUrl: "https://myapi.dev/v1/",
});
export const $api = createClient(fetchClient);
```

:::

## Api

```tsx
const query = $api.useQuery(method, path, options, queryOptions);
```

**Arguments**

- `method` **(required)**
- The HTTP method to use for the request.
- The method is used as key. See [Query Keys](https://tanstack.com/query/latest/docs/framework/react/guides/query-keys) for more information.
- `path` **(required)**
- The pathname to use for the request.
- Must be an available path for the given method in your schema.
- The pathname is used as key. See [Query Keys](https://tanstack.com/query/latest/docs/framework/react/guides/query-keys) for more information.
- `options`
- The fetch options to use for the request.
- Only required if the OpenApi schema requires parameters.
- The options `params` are used as key. See [Query Keys](https://tanstack.com/query/latest/docs/framework/react/guides/query-keys) for more information.
- `queryOptions`
- The original `useQuery` options.
- [See more information](https://tanstack.com/query/latest/docs/framework/react/reference/useQuery)

79 changes: 79 additions & 0 deletions docs/openapi-react-query/use-suspense-query.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
title: useSuspenseQuery
---
# {{ $frontmatter.title }}

The `useSuspenseQuery` method allows you to use the original [useSuspenseQuery](https://tanstack.com/query/latest/docs/framework/react/guides/suspense).

- The result is the same as the original function.
- The `functionKey` is `[method, path, params]`.
- `data` and `error` are fully typed.
- You can pass queries options as fourth parameter.

::: tip
You can find more information about `useSuspenseQuery` on the [@tanstack/react-query documentation](https://tanstack.com/query/latest/docs/framework/react/guides/suspense).
:::

## Example

::: code-group

```tsx [src/app.tsx]
import { ErrorBoundary } from "react-error-boundary";
import { $api } from "./api";

const MyComponent = () => {
const { data } = $api.useSuspenseQuery("get", "/users/{user_id}", {
params: {
path: { user_id: 5 },
},
});

return <div>{data.firstname}</div>;
};

export const App = () => {
return (
<ErrorBoundary fallbackRender={({ error }) => `Error: ${error.message}`}>
<MyComponent />
</ErrorBoundary>
);
};
```

```ts [src/api.ts]
import createFetchClient from "openapi-fetch";
import createClient from "openapi-react-query";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript

const fetchClient = createFetchClient<paths>({
baseUrl: "https://myapi.dev/v1/",
});
export const $api = createClient(fetchClient);
```

:::

## Api

```tsx
const query = $api.useSuspenseQuery(method, path, options, queryOptions);
```

**Arguments**

- `method` **(required)**
- The HTTP method to use for the request.
- The method is used as key. See [Query Keys](https://tanstack.com/query/latest/docs/framework/react/guides/query-keys) for more information.
- `path` **(required)**
- The pathname to use for the request.
- Must be an available path for the given method in your schema.
- The pathname is used as key. See [Query Keys](https://tanstack.com/query/latest/docs/framework/react/guides/query-keys) for more information.
- `options`
- The fetch options to use for the request.
- Only required if the OpenApi schema requires parameters.
- The options `params` are used as key. See [Query Keys](https://tanstack.com/query/latest/docs/framework/react/guides/query-keys) for more information.
- `queryOptions`
- The original `useSuspenseQuery` options.
- [See more information](https://tanstack.com/query/latest/docs/framework/react/reference/useSuspenseQuery)

Loading

0 comments on commit e9a6325

Please sign in to comment.