Skip to content

jibencaozuo-playground/openapi-hooks-codegen

 
 

Repository files navigation

OpenAPI Hooks Codegen

NPM License Node.js Package

Node.js library that generates React Hooks based on the OpenAPI specification.

This project is a fork of openapi-typescript-codegen, which:

  • Generates React hooks for OpenAPI specification, which is driven by jotai;
  • Fixed many bugs in the schema generator, which could help us generate ajv-compliant JSON Schema;
  • Add client-side type validation to enhance the robustness of your website;
  • Dropped the support of OpenAPI v2 and XHR mode;
  • Supports React Native.

Install

npm install @jbcz/openapi-hooks-codegen --save-dev

Notice: React Native users may need react-native-url-polyfill to get the support of baseUrl configuration, please check out the documentation.

Usage

$ openapi --help

  Usage: openapi [options]

  Options:
    -V, --version             output the version number
    -i, --input <value>       OpenAPI specification, can be a path, url or string content (required)
    -o, --output <value>      Output directory (required)

  Examples
    $ openapi --input ./spec.json
    $ openapi --input ./spec.json --output ./dist

Example

Generating

package.json

{
    "scripts": {
        "generate": "openapi --input ./spec.json --output ./dist"
    }
}

Node.js API

const OpenAPI = require('openapi-hooks-codegen');

OpenAPI.generate({
    input: './spec.json',
    output: './dist'
});

// Or by providing the content of the spec directly 🚀
OpenAPI.generate({
    input: require('./spec.json'),
    output: './dist'
});

Using

Basic usage

import { useGetRole } from './api';

const [role, roleController] = useGetRole();

roleController.fetchData(1);

Side effect

Like setting localStorage after a login request.

import { useGetRole } from './api';

const [role, roleController] = useGetRole();

roleController.fetchData(1, {}, (atom, set, result) => {
    set({ ...atom, data: result.body });
    localStorage.setItem('token', result.body);
});

Credential

import { useGetRole, globalOptionsAtom } from './api';

const [role, roleController] = useGetRole();
const [globalConfig, setGlobalConfig] = useAtom(globalOptionsAtom)

setGlobalConfig({
    headers: {
        'Authorization': `Bearer ${localStorage.getItem('token')}`,
    },
});

roleController.fetchData(1);

Request body of a post request

import { useCreateRole } from './api';

const [role, createRoleController] = useCreateRole();

createRoleController.fetchData({
    name: 'xxx',
    permissions: ['xxx'],
    // ...
});

Request header of a request

import { useGetRole } from './api';

const [role, roleController] = useGetRole();

roleController.fetchData(1, {
    headers: {
        'YourHeader': `YourValue`,
        // ...
    },
});

Infinite scrolling

import { useGetRole } from './api';

const [role, roleController] = useGetRole();

roleController.fetchData(1, {}, (atom, set, result) => {
    set({
        ...atom,
        data: atom.data.concat(result),
    })
});

Project Setup

If your team is using Gitea / GitHub and want to automatically sync the spec with the repository, you can use the following project setup:

  1. Installing some dependencies:
yarn add -D npm-run-all dotenv-cli @jbcz/openapi-hooks-codegen
  1. Creating a .env.openapi file in the root directory of your project, with the following content:
GITEA_TOKEN=YOUR_SUPER_SECRET_TOKEN
GITHUB_TOKEN=YOUR_SUPER_SECRET_TOKEN

You can get your token from:

  1. Adding the following configuration to the scripts section of your package.json file:
"scripts": {
    "sync-spec": "dotenv -e /env.openapi -- openapi-sync-gitea --ref RELEASE_TAG --owner REPO_OWNER --repo REPO_ID --filePath FILE_PATH_IN_THE_REPO --host GITEA_HOST -o ./spec.yaml",
    "gen-api": "openapi --input ./spec.yaml --output ./src/api/",
    "postinstall": "npm-run-all sync-spec gen-api",
},

openapi-sync-gitea could be replaced to openapi-sync-github, in case you are using self hosted GitHub for Enterprise, the --host can be customized, and default value is set to api.github.com.

  1. Creating a .gitkeep file in the ./src/api/.

  2. IMPORTANT: Add the following configuration to your .gitignore file:

/env.openapi
/spec.yaml
/src/api/
!/src/api/.gitkeep
  1. Edit tsconfig.json to add the following configuration:
{
  "compilerOptions": {
      "baseUrl": "src",
  }
}
  1. Run yarn postinstall to generate the API.

FAQ

Babel support

If you use enums inside your models/definitions then those enums are by default inside a namespace with the same name as your model. This is called declaration merging. However, the @babel/plugin-transform-typescript does not support these namespaces, so if you are using babel in your project please use the --useUnionTypes flag to generate union types instead of traditional enums. More info can be found here: Enums vs. Union Types.

Note: If you are using Babel 7 and Typescript 3.8 (or higher) then you should enable the onlyRemoveTypeImports to ignore any 'type only' imports, see https://babeljs.io/docs/en/babel-preset-typescript#onlyremovetypeimports for more info

module.exports = {
    presets: [
        ['@babel/preset-typescript', {
            onlyRemoveTypeImports: true,
        }],
    ],
};

About

Library that generates React Hooks based on the OpenAPI specification.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 66.0%
  • Handlebars 19.2%
  • JavaScript 14.8%