UNPKG

8.19 kBMarkdownView Raw
1# swagger-gen-js
2`swagger-gen-js` is a code generation tool. It takes as input a swagger specification for an API and produces redux reducers, redux actions, redux sagas, selectors, api middleware, and/or flow types suitable for use in a React/Redux based web application.
3
4## Goals
5The goal of `swagger-gen-js` is to remove as much as possible of the boilerplate normally required to write a full-featured `redux`/`redux-saga`-based webapp. A moderately complicated project using `redux-saga` to handle making API calls as side effects to `redux` actions can easily require thousands of lines of boilerplate redux actions, reducers, and sagas just to do repetitive tasks. This leaves the project open to subtle inconsistencies and bugs in API interaction logic, vastly more code to maintain, and wasted devloper effort on otherwise simple tasks.
6
7# How to Use
8
9## Runtime options
10The command line options are:
11
12* `-d` or `--debug`: If set, builds produce logging output in `./log`. Default: false. Debug may also be set in the config file as described below.
13* `-o` or `--options`: String path to the config file. Default: `./.swaggergenrc'`.
14* `-v` or `--verbose`: If set, build progress is reported via `console.info()`. Default: false
15
16## Configuration
17Most `swagger-gen-js` configuration is done with a configuration file. For details, see [Configuration](./CONFIGURATION.md).
18
19## Best Practices
20There is little point to using `swagger-gen-js` without generating (at least) reducers, sagas, selectors, action creators, and flow types. These guidelines assume these are all available.
21
22### Generation settings
23`swagger-gen-js` output should not share directories with handwritten code. A simple way to achieve this is to give all the directory paths a suffix like `_gen`. This also makes it easier to clean all generated code before builds. The generated output directories should be relatively close together in the directory tree. This will make it easier to trace the relationships between the generated files and make their output more readable.
24
25Use [`operationId` translations](./CONFIGURATION.md#`translate_operationId`) for the endpoints you plan to use. This allows you to make the output more readable. In cases where `operationId`s in specifications change while the endpoints stay the same (such as when upgrading to a new spec version) having such translations will you to change the target `operationId` without needing to update imports everywhere the generated output is consumed. Do not use `operationId` translations for endpoints you are not using, as it will make the configuration file unncessarily long and obscure what you actually care about using in your app.
26
27Use the [`output.include` config option](./CONFIGURATION.md#`output.include`) to whitelist the tags to generate. This makes it easier to see which modules you're actually using. It also means the generated reducer won't fill your store with unused state.
28
29Take advantage of the generated flow types when preparing actions to trigger API requests. Each api module exports flow types for the request body and params it expects. You can use these in your handwritten sagas to detect malformed data before making the request at all.
30
31### Convenience features
32The generated reducers directory includes an `index.js` which exports a reducer combining all the generated reducers and an accompanying flow type. Composing the generated reducer into your store reduces the boilerplate involved in consuming all the generated reducers individually. If you do this, remember to put the reducer in the same place in the store as was configured in the [`api_reducer_location` config option](./CONFIGURATION.md#`api_reducer_location`).
33
34`swagger-gen-js` uses a recent version of `redux-actions`. As a result, the generated action creators do not require separately defined action constants. When listening for a generated action type, use the `toString()` method of the action creator. This makes it easier to search for where a given action is being used, and saves the boilerplate of separately defining and exporting string constants. Similarly, reducers created with `handleActions()` can be created using a `Map` keyed by the action creators directly instead of an object which must be keyed by a string.
35
36### What not to use
37Avoid using the [`output.spec_overrides` config option](./CONFIGURATION.md#`output.spec_overrides`) in the long term. It is intended for cases where a specification does not match the actual behavior of the API it documents. In cases like those, you should do your best to have a fix implemented upstream. The spec override will allow you to continue work while the issue is resolved. Overrides should be removed as soon as they cease to be relevant.
38
39Avoid storing data returned from an api call in handwritten reducers unless there is a specific need. Doing so runs the risk of contradictions between local and server-side versions of data or of subtle errors in the locally stored data. The generated reducer handles storing the most recent successes and failures. Good reasons to store data in handwritten reducers are for extra caching (eg. storing multiple preceding exceptions) and for keeping a subset of a response for persistence (eg. storing only a part of a customer profile in a cookie).
40
41Do not access the generated state directly - instead, use the generated selectors. This will provide you with stronger type checking and allow you to benefit from memoization.
42
43Do not use the generated action creators for ANYTHING except triggering and handling api interaction. This means that usually the only generated actions you should dispatch should be the `REQUEST` actions, and only for the sole purpose of commencing API activity. The response actions are useful for eg. dispatching an analytics event in the event of a server exception, but should not be used manually for such purposes. Doing so will overwrite the data stored in the generated reducers.
44
45Avoid using the api modules directly. They are available in case you need to use them in some way outside the assumptions made by `swagger-gen-js`, but by using them directly you lose all the redux-related benefits of `swagger-gen-js` and must handle input validation and responses entirely on your own.
46
47### What to commit
48There are a few ways to use `swagger-gen-js`.
49
50The first way to use it is as a build-time tool to generate code used at runtime. In this case, the json input files should be committed to the repo. The upside to this approach is that there is only one source of truth as to what is actually produced. The downside is that a substantial portion of the actual content of a build is only known for sure at build time. In this case, the output target directories should be added to `.gitignore`. *Most projects currently using `swagger-gen-js` follow this pattern, and it is the one we recommend in general.*
51
52`swagger-gen-js` provides a utility to download a swagger spec at build time based on the [`specs` setting](./Configuration#`specs`) in the config file. You can use that at build time to select a spec to use instead of committing the spec file. In this case you have the advantage of always using the latest spec, but you will no longer have reproducible builds.
53
54`swagger-gen-js` also works as dev-time tool to generate code which is then committed to the repo directly. In this case, the generated files are committed. It is often helpful in this case to commit the source specs as well, but that runs the risk of the two getting out of sync. The upside to this approach is that it's very clear what actual code has changed when updating to new spec versions or changing settings. The downside is that the potentially large number of lines changed in response to configuration changes or minor spec revisions can make the diffs less useful.
55
56## Utility Modules
57`swagger-gen-js` exposes some internal utilities for use alongside `swagger-gen-js`-generated code, or even alone.
58
59For documentation on the available utilities, see [Utilities](./utilities/README.md).
60
61## Internal API
62For documentation on the inner workings of `swagger-gen-js`, refer to [Generators](./src/README.md).