tidepool-standard-action
Version:
Tidepool's (enforceable!) standard for redux action objects.
133 lines (78 loc) • 5.07 kB
Markdown
# tidepool-standard-action
[](https://travis-ci.org/tidepool-org/tidepool-standard-action)
## Justification
(Or jump to [The Standard](#introduction).)
[Tidepool](https://github.com/tidepool-org/ 'Tidepool on GitHub')'s (enforceable!) standard for redux action objects.
Inspired by [flux-standard-action](https://github.com/acdlite/flux-standard-action 'GitHub: flux-standard-action') but tailored specifically to Tidepool's needs.
> Yes, we are aware of the irony, and we've seen [that XKCD comic](https://xkcd.com/927/ 'xkcd: Standards').
We've created this repository because the flux-standard-action (FSA) project failed us in two places:
1. The `isFSA()` function exposed by FSA does *not* validate the action objects to the level of detail that we require in our heavily-tested applications. 😕
1. FSA's decision to represent error actions with a Boolean `true` in the `error` field, and a JavaScript `Error` object *as* the `payload` causes us problems in a small but significant number of cases where we need *other* information in the `payload` besides the `Error` object in order to update our state tree accurately. In other words, we agree with many of those who chimed in on [FSA's Issue #17](https://github.com/acdlite/flux-standard-action/issues/17 'GitHub: flux-standard-action Issue #17').
In short, since we (at Tidepool) have several applications where we need to adhere to a standard for actions (and validate that standard in unit tests!), we have decided<sup>[1](#footnote)</sup> to create our own standard and utility for this purpose. Others are welcome to adopt our standard as well, but we're not going to be evangelical about it. 😉
<a name="footnote">1</a>: For posterity: @jebeck, in particular, is to blame here, with encouragement from @GordyD.
The remainder of this README is a modified version of [FSA's README](https://github.com/acdlite/flux-standard-action/blob/master/README.md 'GitHub: flux-standard-action README').
## Introduction
A Tidepool-friendly standard for redux action objects. Because we needed it.
### Motivation
It's much easier to work with redux actions if we can make certain assumptions about their shape. For example, all redux actions have a `type` identifier field. Many redux actions also include some payload of data that will be used by the reducers to modify the state tree. Defining a common standard for these patterns enables the creation of useful tools and abstractions and makes our lives easier as developers working on more than one app.
### Design goals
- **Human-friendly.** TSA actions should be easy to read and write by humans.
- **Useful**. TSA actions should enable the creation of useful tools and abstractions.
- **Simple.** TSA should be simple, straightforward, and *opinionated* in its design. (Loose standards aren't easily enforceable!)
### Example
A basic Tidepool Standard Action (TSA):
```js
{
type: 'ADD_TODO_SUCCESS',
payload: {
text: 'Fry up some bacon.'
}
}
```
#### Error Example
A TSA that represents an error:
```js
{
type: 'ADD_TODO_FAILURE',
error: new Error('Error adding a TODO :('),
payload: {userId: 'a1b2c3'}
}
```
## Actions
An action MUST
- be a plain JavaScript object.
- have a `type` property.
An action MAY
- have an `error` property.
- have a `payload` property.
- have a `meta` property.
IFF an action has an `error` property, the `error` property MUST
- be a JavaScript `Error` object.
IFF an action has a `payload` property, the `payload` property MUST
- be a plain JavaScript object.
IFF an action has a `meta` property, the `meta` property MUST
- be a plain JavaScript object.
An action MUST NOT include properties other than `type`, `payload`, and `error`, and `meta`.
### `type`
The `type` of an action identifies to the consumer the nature of the action that has occurred. In a TSA, `type` MUST be a JavaScript `String` constant.
### `error`
The optional `error` property MUST be a JavaScript `Error` object. It indicates that the action be interpreted as an error action.
### `payload`
The optional `payload` property MUST be a plain JavaScript object. It represents the payload of the action. Any information about the action that is not the `type` or status of the action should be part of the `payload` object.
### `meta`
The optional `meta` property MUST be a plain JavaScript object. It is intended for any extra information that is not part of the `payload`.
## Testing utility
This module (tidepool-standard-action) is published on [npm](https://www.npmjs.com/ 'npm'). It exports an `isTSA` utility function that may be used as follows:
ES5, assuming use of CommonJS modules:
```js
var isTSA = require('tidepool-standard-action');
var action = {...};
isTSA(action);
```
ES6/ES2015:
```js
import isTSA from 'tidepool-standard-action';
const action = {...};
isTSA(action);
```
`isTSA` returns `true` if `action` complies with the standard described above and `false` otherwise.