/react-openapi-hooks-gen

An OpenAPI 3 codegen for React Hooks using Typescript

Primary LanguageTypeScriptMIT LicenseMIT

react-openapi-hooks-gen: An OpenAPI 3 code generator for React using hooks, redux, and typescript

Build Status test

This project is a NPM module that generates model interfaces, redux actions and reducers, and hooks from an OpenApi 3 specification. The generated classes follow the principles of React. The generated code is compatible with React v16.13.1.

Highlights

  • It should be easy to use and to integrate with Create React App CLI;
  • It should support OpenAPI specifications in both JSON and YAML formats;
  • OpenAPI supports combinations of request body and response content types. For each combination, a distinct method is generated;
  • It should be possible to specify a subset of reducers to generate. Only the models actually used by that subset should be generated;
  • It should be easy to specify a root URL for the web service endpoints;
  • Generated files should compile using strict TypeScript compiler flags, such as noUnusedLocals and noUnusedParameters.
  • It should use the standard fetch api
  • It should use redux to easily allow devs to see current state and actions being fired
  • It should expose functionality to views through custom hooks

Limitations

  • Only standard OpenAPI 3 descriptions will be generated. react-openapi-hooks-gen allows several extensions, specially types from JSON schema, but they are out of scope for react-openapi-hooks-gen. There is, however, support for a few vendor extensions;
  • Servers per operation are not supported;
  • Only the first server is used as a default root URL in the configuration;
  • No data transformation is ever performed before sending / after returning data. This means that a property of type string and format date-time will always be generated as string, not Date. Otherwise every API call would need to have a processing that would traverse the returned object graph before sending the request to replace all date properties by Date. The same applies to sent requests. Such operations are out of scope for react-openapi-hooks-gen;

Installing and running

You may want to install react-openapi-hooks-gen globally or just on your project. Here is an example for a global setup:

$ npm install -g react-openapi-hooks-gen
$ react-openapi-hooks-gen --input my-api.yaml --output my-app/src/api

This will expect the file my-api.yaml to be in the current directory, and will generate the files on my-app/src/api.

Configuration file and CLI arguments

If the file react-openapi-hooks-gen.json exists in the current directory, it will be read. Alternatively, you can run react-openapi-hooks-gen --config my-config.json (could also be -c) to specify a different configuration file, or even specify the input / output as react-openapi-hooks-gen -i input.yaml or react-openapi-hooks-gen -i input.yaml -o /tmp/generation. The only required configuration property is input, which specified the OpenAPI specification file. The default output is src/api.

For a list with all possible configuration options, see the JSON schema file. You can also run react-openapi-hooks-gen --help to see all available options. Each option in the JSON schema can be passed in as a CLI argument, both in camel case, like --includeTags tag1,tag2,tag3, or in kebab case, like --exclude-tags tag1,tag2,tag3.

Here is an example of a configuration file:

{
  "$schema": "node_modules/react-openapi-hooks-gen/react-openapi-hooks-gen-schema.json",
  "input": "my-file.json",
  "output": "out/person-place",
  "ignoreUnusedModels": false
}

Specifying the root URL / web service endpoint

TBD

Passing request headers / customizing the request

TBD

Supported vendor extensions

Besides the OpenAPI 3 specification, the following vendor extensions are supported:

  • x-operation-name: Defined in LoopBack, this extension can be used in operations to specify the actual method name. The operationId is required to be unique among all tags, but with this extension, a shorter method name can be used per tag (service). Example:
paths:
  /users:
    get:
      tags:
        - Users
      operationId: listUsers
      x-operation-name: list
      # ...
  /places:
    get:
      tags:
        - Places
      operationId: listPlaces
      x-operation-name: list
      # ...
  • x-enumNames: Generated by NSwag, this extension allows schemas which are enumerations to customize the enum names. It must be an array with the same length as the actual enum values. Example:
components:
  schemas:
    HttpStatusCode:
      type: integer
      enum:
        - 200
        - 404
        - 500
      x-enumNames:
        - OK
        - NOT_FOUND
        - INTERNAL_SERVER_ERROR

Developing and contributing

The generator itself is written in TypeScript. When building, the code is transpiled to JavaScript in the dist folder. And the dist folder is the one that gets published to NPM. Even to prevent publishing from the wrong path, the package.json file has "private": true, which gets replaced by false in the build process.

On the other hand, for developing / running tests, jasmine-ts is used, so the tests run directly from TypeScript. There's even a committed VisualStudio Code debug configuration for tests.

After developing the changes, to link the module and test it with other node projects, run the following:

npm run build
cd dist
npm link

At that point, the globally available react-openapi-hooks-gen will be the one compiled to the dist folder.