Skip to content

Latest commit

 

History

History
296 lines (220 loc) · 14.1 KB

README.md

File metadata and controls

296 lines (220 loc) · 14.1 KB





npm Read the documentation

Tooling to give you full type-safety around OpenAPI specs.

You can generate

Getting started

  1. Initialize the generator

    npx @openapi-codegen/cli init

    If you wish to change any of the selections made, you can do so in the generated openapi-codegen.config.ts file later..

  2. Start Generation

    npx openapi-codegen gen {namespace}

    After the code generation is done, you will notice the following files:

    • {namespace}Fetcher.ts - defines a function that will make requests to your API.
    • {namespace}Context.tsx - the context that provides {namespace}Fetcher to other components.
    • {namespace}Components.tsx - generated React Query components (if you selected React Query as part of initialization).
    • {namespace}Schemas.ts - the generated Typescript types from the provided Open API schemas.

     

    Warning

    If {namespace}Fetcher.ts or {namespace}Context.tsx already exist in the output folder, they will not be replaced. However, {namespace}Components.tsx and {namespace}Schemas.ts will be re-generated each time based on the Open API spec file provided.

  3. Configure the Fetcher (optional)

    After the first step you should see a file called {namespace}Fetcher.ts in your ouput directory. This file

    By default it uses the built-in Fetch API, you are free to change this to your fetching library of choice (Axios, Got etc.)

    If your Open API spec contains a configured server, then the base URL for all requests will default to that server's URL. If no such configuration exists, you'll need to specify the base URL value.

  4. Install and Configure React Query (optional)

    If during generator setup you picked > React Query components, then you will need to install and configure React Query in order for the generated React hooks to work properly:

    • Install the library

      npm i @tanstack/react-query
    • Wire up the QueryClient as described here.

Usage

React Query components

Using [https://api.apis.guru/v2/specs/giphy.com/1.0/openapi.yaml](giphy specs) as example

This will generate lot of ready-to-use hooks like:

  • useRandomGif -> Wrapper around useQuery with injected types
  • useSuspenseRandomGif -> Same but with useSuspense

And you will have some useMutation if the api expose some (not the case with this example)

Here an example of usage of this generated api:

import { useRandomGif } from "./giphy";

export function GifExplorer() {
  const [tag, setTag] = useState("");
  const { data, error, isError, isPending } = useRandomGif({
    queryParams: {
      tag,
    },
  });

  return (
    <div>
      <input value={tag} onChange={(e) => setTag(e.currentTarget.value)} />
      {isPending ? (
        <div>Loading…</div>
      ) : isError ? (
        <div>
          <pre>{error.payload ?? "Unknown error"}</pre>
        </div>
      ) : (
        // This is typed!
        <img src={data.data?.url} />
      )}
    </div>
  );
}

This also support reactQuery.skipToken to stay type-safe when you are waiting for params:

+ import { skipToken } from "@tanstack/react-query";

- const { data, error, isError, isPending } = useRandomGif({
-     queryParams: {
-       tag,
-     },
-   });
+ const { data, error, isError, isPending } = useRandomGif(
+     tag
+       ? skipToken
+       : {
+           queryParams: {
+             tag,
+           },
+         }
+   );

You can also use directly the queryFn for more advanced use cases:

import { randomGifQuery } from "./giphy/giphyComponents";

const queryClient = new QueryClient();

queryClient.fetchQuery(randomGifQuery({}));

Configuration

The only thing you need to manage is the configuration. Everything is typed and self-documented, but just in case, you can find here example configuration below:

Example Config

// openapi-codegen.config.ts
import { defineConfig } from "@openapi-codegen/cli";
import {
  generateSchemaTypes,
  generateReactQueryComponents,
} from "@openapi-codegen/typescript";

export default defineConfig({
  example: {
    // can be overridden from cli
    from: {
      source: "github",
      owner: "fabien0102",
      repository: "openapi-codegen",
      ref: "main",
      specPath: "examples/spec.yaml",
    },

    // can be overridden from cli
    outputDir: "src/queries",

    to: async (context) => {
      // You can transform the `context.openAPIDocument` here, can be useful to remove internal routes or fixing some known issues in the specs ;)

      // Generate all the schemas types (components & responses)
      const { schemasFiles } = await generateSchemaTypes(context, {
        /* config */
      });

      // Generate all react-query components
      await generateReactQueryComponents(context, {
        /* config*/
        schemasFiles,
      });
    },
  },
});

Plugins

the @openapi-codegen/cli supports these generator plugins:

generateSchemaTypes (frontend/backend)

generate all schema types for your specification:

const { schemasFiles } = await generateSchemaTypes(context, {
  /* config */
});

output: {namespace}Schemas.ts

generateFetchers (frontend)

generate all fetchers with types for your specification

await generateFetchers(context, {
  /* config */
  schemasFiles,
});

output: {namespace}Fetchers.ts

generateReactQueryComponents (frontend)

generate all React Query Components for useQuery() and useMutation()

await generateReactQueryComponents(context, {
  /* config*/
  schemasFiles,
});

output: {namespace}Components.ts

This is also generate a query function that can be used in most of React Query functions.

Example with queryClient.fetchQuery (data loader case):

await queryClient.fetchQuery(getYourQueryNameQuery({}));

You can import any generator into the to section, those can be the ones provided by this project or your own custom ones. You have full control of what you are generating!

Have fun!

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Fabien BERNARD
Fabien BERNARD

💻 🎨 📖 🤔 📆 👀
mpotomin
mpotomin

💻 🤔 👀
Michael Franzkowiak
Michael Franzkowiak

📖
Alexis Rico
Alexis Rico

💻 🤔
Nedim Arabacı
Nedim Arabacı

💬 💻 🤔
Antoniel Magalhães
Antoniel Magalhães

💡 🐛
Florian Dreier
Florian Dreier

💻
Fabian Althaus
Fabian Althaus

💻
ci-vamp
ci-vamp

🐛 💻
Alan Oliveira
Alan Oliveira

💻
Michael "Mike" Ferris
Michael "Mike" Ferris

💻
Jan Šilhan
Jan Šilhan

🐛 💻 📖
Daniel Cooke
Daniel Cooke

🐛 💻
Linden Wright
Linden Wright

💻
Valeriy
Valeriy

🐛 💻 🤔

This project follows the all-contributors specification. Contributions of any kind welcome!