Quick Start
To get started with OpenAPI Qraft, you first need to generate types from your OpenAPI Document, and also generate services that will use these types to interact with your API.
1. Generate OpenAPI Types & Servicesโ
Assumed that you already installed @openapi-qraft/react
package โ
- Instant
CLI
package.json
setup
Run the following command in the root directory of your project using your package manager.
npx @openapi-qraft/cli@next --plugin tanstack-query-react --plugin openapi-typescript \
--output-dir src/api https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml
Add the following scripts
and devDependencies
to your package.json
:
{
"scripts": {
"generate-client": "openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml --output-dir src/api"
},
"devDependencies": {
"@openapi-qraft/cli": "latest"
},
"dependencies": {
"@openapi-qraft/react": "latest"
}
}
Then run the following command in the root directory of your project:
- npm
- yarn
- pnpm
npm install
npm run generate-client
yarn install
yarn generate-client
pnpm install
pnpm run generate-client
info
openapi-qraft
creates service files in the src/api
directory of your project:
src/
โโโ api/
โ โโโ schema.d.ts # โฌ
๏ธ Types generated by `--plugin openapi-typescript`
โ โ # โฌ๏ธ Files generated by `--plugin tanstack-query-react`
โ โโโ create-api-client.ts # Generated function to create the API client
โ โโโ services/ # Generated services
โ โโโ PetService.ts
โ โโโ StoreService.ts
โ โโโ UserService.ts
--clean
option could be useful. With the option,src/api/services
directory will be cleared before the new services are generated.
2. Use the generated services in your React applicationโ
Here are examples of how to use the generated services in your React application with
useQuery
, useMutation
, and useInfiniteQuery
hooks from TanStack Query.
- useQuery(...)
- useMutation(...)
- useInfiniteQuery(...)
src/App.tsx
import { createAPIClient } from './api'; // generated by OpenAPI Qraft
import { QraftContext, requestFn } from '@openapi-qraft/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useMemo } from 'react';
// The `createAPIClient(...)` function is generated by OpenAPI Qraft
// The `qraft` object could be created in a separate file and imported,
// or created multiple times in different components.
// It's just a shortcut to TanStack Query Hooks!
const qraft = createAPIClient();
function ExamplePetDetails({ petId }: { petId: number }) {
/**
* Executes the request to the API on mount:
* ###
* GET /pet/123456
**/
const {
data: pet,
isPending,
error,
} = qraft.pet.getPetById.useQuery({
path: { petId },
});
if (isPending) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return <div>Pet Name: {pet?.name}</div>;
}
export default function App() {
const queryClient = useMemo(() => new QueryClient(), []);
return (
<QueryClientProvider client={queryClient}>
<QraftContext.Provider
value={{
baseUrl: 'https://petstore3.swagger.io/api/v3', // the base URL of the API
requestFn, // the request function to use, could be fully customized
}}
>
<ExamplePetDetails petId={123456} />
</QraftContext.Provider>
</QueryClientProvider>
);
}
src/App.tsx
import { createAPIClient } from './api'; // generated by OpenAPI Qraft
import { QraftContext, requestFn } from '@openapi-qraft/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useMemo } from 'react';
function EntityForm({ entityId }: { entityId: string }) {
const mutation = qraft.entities.postEntitiesIdDocuments.useMutation({
// Usage of `*.useMutation()` without predefined `parameters` is also possible
path: {
entity_id: entityId
},
header: {
'x-monite-version': '2023-09-01',
},
});
return (
<form
onSubmit={(event) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
/**
* Executes the request`:
* ###
* POST /entities/3e3e-3e3e-3e3e/documents
* x-monite-version: 2023-09-01
*
* {"company_tax_id_verification": ["verification-id"]}
**/
mutation.mutate({
company_tax_id_verification: [
String(formData.get('company_tax_id_verification')),
],
});
}}
>
<input name="company_tax_id_verification" />
<button>Submit</button>
</form>
);
}
export default function App() {
const queryClient = useMemo(() => new QueryClient(), []);
return (
<QueryClientProvider client={queryClient}>
<QraftContext.Provider
value={{
baseUrl: 'https://api.sandbox.monite.com/v1', // the base URL of the API
requestFn, // the request function to use, could be fully customized
}}
>
<EntityForm entityId="3e3e-3e3e-3e3e" />
</QraftContext.Provider>
</QueryClientProvider>
);
}
src/PostList.tsx
import { createAPIClient } from './api'; // generated by OpenAPI Qraft
const qraft = createAPIClient();
/**
* Executes the initial request:
* ###
* GET /posts?limit=10&page=1
**/
function PostList() {
const infiniteQuery = qraft.posts.getPosts.useInfiniteQuery(
{ query: { limit: 10 } },
{
// * required by TanStack Query
getNextPageParam: (lastPage, allPages, lastPageParams) => {
if (lastPage.length < 10) return; // if less than 10 items, there are no more pages
return {
query: {
page: Number(lastPageParams.query?.page) + 1,
},
};
},
// * required by TanStack Query
initialPageParam: {
query: {
page: 1, // will be used in initial request
},
},
}
);
return (
<div>
{infiniteQuery.data?.pages.map((page, pageIndex) => (
<ul key={pageIndex}>
{page.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
))}
<button onClick={() => {
// โฌ๏ธ Executes GET /posts?limit=10&page=2
infiniteQuery.fetchNextPage()
}}>
Load More
</button>
</div>
);
}