{"_id":"@aftonbladet/redux-api-middleware","_rev":"10-878d7cc84de258d040a18564754e05be","name":"@aftonbladet/redux-api-middleware","description":"Redux middleware for calling an API.","dist-tags":{"latest":"1.1.1"},"versions":{"1.0.2-0":{"name":"@aftonbladet/redux-api-middleware","version":"1.0.2-0","description":"Redux middleware for calling an API.","main":"lib/index.js","scripts":{"build":"babel src --out-dir lib","clean":"rimraf lib coverage","cover":"babel-node ./node_modules/.bin/babel-istanbul cover test/index.js | tap-spec","lint":"eslint src test","prepublish":"npm run lint && npm test && npm run clean && npm run build","test":"babel-node test/index.js | tap-spec"},"repository":{"type":"git","url":"git+https://github.com/agraboso/redux-api-middleware.git"},"homepage":"https://github.com/agraboso/redux-api-middleware","keywords":["redux","api","middleware","redux-middleware","flux"],"author":{"name":"Alberto Garcia-Raboso","email":"agraboso@gmail.com"},"license":"MIT","dependencies":{"babel-runtime":"^5.8.25","isomorphic-fetch":"^2.1.1","lodash.isplainobject":"^3.2.0"},"devDependencies":{"babel":"^5.8.23","babel-eslint":"^4.1.3","babel-istanbul":"^0.3.20","coveralls":"^2.11.4","eslint":"^1.6.0","eslint-plugin-babel":"^2.1.1","nock":"^2.15.0","normalizr":"^1.1.0","rimraf":"^2.4.3","tap-spec":"^4.1.0","tape":"^4.2.1"},"files":["README.md","LICENSE.md","lib/"],"gitHead":"c3531287de1dab67847546c09ebad2823d28ab95","bugs":{"url":"https://github.com/agraboso/redux-api-middleware/issues"},"_id":"@aftonbladet/redux-api-middleware@1.0.2-0","_shasum":"b0f32c609f4ba2eb9949a1adce34646d6dfedfa5","_from":".","_npmVersion":"3.9.5","_nodeVersion":"6.2.2","_npmUser":{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"},"dist":{"shasum":"b0f32c609f4ba2eb9949a1adce34646d6dfedfa5","tarball":"https://registry.npmjs.org/@aftonbladet/redux-api-middleware/-/redux-api-middleware-1.0.2-0.tgz","integrity":"sha512-fiZlG+j6FuG56VRwv6+sjFuS5F9b6wcAr2Lv2pNlyIFmhSwtKklwP56gY3fgnFrgMfvsijFxLMRNS+4S56Dprw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCrYzik29MPeAwLd6/FlV6zlQ9ERAqUWDWNYNL0fltoEAIhAM4OmMHUiviMtGgtUJkL0Lm3KCfuekLFDErfmar+i0Yu"}]},"maintainers":[{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/redux-api-middleware-1.0.2-0.tgz_1473945382750_0.37488285382278264"}},"1.0.2-1":{"name":"@aftonbladet/redux-api-middleware","version":"1.0.2-1","description":"Redux middleware for calling an API.","main":"lib/index.js","scripts":{"build":"babel src --out-dir lib","clean":"rimraf lib coverage","cover":"babel-node ./node_modules/.bin/babel-istanbul cover test/index.js | tap-spec","lint":"eslint src test","prepublish":"npm run lint && npm test && npm run clean && npm run build","test":"babel-node test/index.js | tap-spec"},"repository":{"type":"git","url":"git+https://github.com/agraboso/redux-api-middleware.git"},"homepage":"https://github.com/agraboso/redux-api-middleware","keywords":["redux","api","middleware","redux-middleware","flux"],"author":{"name":"Alberto Garcia-Raboso","email":"agraboso@gmail.com"},"license":"MIT","dependencies":{"babel-runtime":"^6","isomorphic-fetch":"^2.1.1","lodash.isplainobject":"^3.2.0"},"devDependencies":{"babel-cli":"^6","babel-eslint":"^6","babel-istanbul":"^0.3.20","babel-preset-es2015":"^6","babel-preset-stage-0":"^6","coveralls":"^2.11.4","eslint":"^1.6.0","eslint-plugin-babel":"^2.1.1","nock":"^2.15.0","normalizr":"^1.1.0","rimraf":"^2.4.3","tap-spec":"^4.1.0","tape":"^4.2.1"},"files":["README.md","LICENSE.md","lib/"],"gitHead":"e1e252a7eb4ac069c3b3918180cc1340c08d6040","bugs":{"url":"https://github.com/agraboso/redux-api-middleware/issues"},"_id":"@aftonbladet/redux-api-middleware@1.0.2-1","_shasum":"0386f607c934523400611f50551fcdccea79e967","_from":".","_npmVersion":"3.9.5","_nodeVersion":"6.2.2","_npmUser":{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"},"dist":{"shasum":"0386f607c934523400611f50551fcdccea79e967","tarball":"https://registry.npmjs.org/@aftonbladet/redux-api-middleware/-/redux-api-middleware-1.0.2-1.tgz","integrity":"sha512-LtUeEo60AYewKmBfqhtoOPlnhOZSEpxv0gsTMPoLewGICuQEwmqb7hQC0aNKIaV1ZMIdWxFk9MYOeD5Qo0xCNQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCXHsiWiLme5pyoBc9RpxvoY0tm74n0EvNShjvAJZMsqAIhALI9zrBEn4uemvQvu6R7Fi2EcTZDOiQOl4f1GkGQgUHL"}]},"maintainers":[{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/redux-api-middleware-1.0.2-1.tgz_1473948281318_0.2513111650478095"}},"1.0.2-2":{"name":"@aftonbladet/redux-api-middleware","version":"1.0.2-2","description":"Redux middleware for calling an API.","main":"lib/index.js","scripts":{"build":"babel src --out-dir lib","clean":"rimraf lib coverage","cover":"babel-node ./node_modules/.bin/babel-istanbul cover test/index.js | tap-spec","lint":"eslint src test","prepublish":"npm run lint && npm test && npm run clean && npm run build","test":"babel-node test/index.js | tap-spec"},"repository":{"type":"git","url":"git+https://github.com/agraboso/redux-api-middleware.git"},"homepage":"https://github.com/agraboso/redux-api-middleware","keywords":["redux","api","middleware","redux-middleware","flux"],"author":{"name":"Alberto Garcia-Raboso","email":"agraboso@gmail.com"},"license":"MIT","dependencies":{"babel-runtime":"^6","isomorphic-fetch":"^2.1.1","lodash.isplainobject":"^3.2.0"},"devDependencies":{"babel-cli":"^6","babel-eslint":"^6","babel-istanbul":"^0.3.20","babel-plugin-transform-runtime":"^6","babel-preset-es2015":"^6","babel-preset-stage-0":"^6","coveralls":"^2.11.4","eslint":"^1.6.0","eslint-plugin-babel":"^2.1.1","nock":"^2.15.0","normalizr":"^1.1.0","rimraf":"^2.4.3","tap-spec":"^4.1.0","tape":"^4.2.1"},"files":["README.md","LICENSE.md","lib/"],"gitHead":"e7bd9a03853c7492f19372722326bab7cf325d93","bugs":{"url":"https://github.com/agraboso/redux-api-middleware/issues"},"_id":"@aftonbladet/redux-api-middleware@1.0.2-2","_shasum":"8dfd49391c483d88d4b59a7ba7332c51f2082db5","_from":".","_npmVersion":"3.9.5","_nodeVersion":"6.2.2","_npmUser":{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"},"dist":{"shasum":"8dfd49391c483d88d4b59a7ba7332c51f2082db5","tarball":"https://registry.npmjs.org/@aftonbladet/redux-api-middleware/-/redux-api-middleware-1.0.2-2.tgz","integrity":"sha512-PPkxgkXj/orU/w7tP/PjKpvgnDMIi71xjeVg7OjS4AzKfl8MLw78NQAUCfeo05VbVZQm2XNc5nVFyEAM0xMtpg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD8KE1TJQ6IEHe00AgVikrKGBx554bT1oPt4ia+JwZgbgIgLKWNi70Q6sSzypyQ8xMnEnBd6d/x/TasobQBU/CRwvk="}]},"maintainers":[{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/redux-api-middleware-1.0.2-2.tgz_1473961360554_0.9868015677202493"}},"1.0.2-3":{"name":"@aftonbladet/redux-api-middleware","version":"1.0.2-3","description":"Redux middleware for calling an API.","main":"lib/index.js","scripts":{"build":"babel src --out-dir lib","clean":"rimraf lib coverage","cover":"babel-node ./node_modules/.bin/babel-istanbul cover test/index.js | tap-spec","lint":"eslint src test","prepublish":"npm run lint && npm test && npm run clean && npm run build","test":"babel-node test/index.js | tap-spec"},"repository":{"type":"git","url":"git+https://github.com/agraboso/redux-api-middleware.git"},"homepage":"https://github.com/agraboso/redux-api-middleware","keywords":["redux","api","middleware","redux-middleware","flux"],"author":{"name":"Alberto Garcia-Raboso","email":"agraboso@gmail.com"},"license":"MIT","dependencies":{"babel-runtime":"^6","isomorphic-fetch":"^2.1.1","lodash.isplainobject":"^3.2.0"},"devDependencies":{"babel-cli":"^6","babel-eslint":"^6","babel-istanbul":"^0.3.20","babel-plugin-transform-runtime":"^6","babel-preset-es2015":"^6","babel-preset-stage-0":"^6","coveralls":"^2.11.4","eslint":"^1.6.0","eslint-plugin-babel":"^2.1.1","nock":"^2.15.0","normalizr":"^1.1.0","rimraf":"^2.4.3","tap-spec":"^4.1.0","tape":"^4.2.1"},"files":["README.md","LICENSE.md","lib/"],"gitHead":"2780b9f4be9d309666684ead4861d2e868a83612","bugs":{"url":"https://github.com/agraboso/redux-api-middleware/issues"},"_id":"@aftonbladet/redux-api-middleware@1.0.2-3","_shasum":"9798eab5e83be7b061b48908b08476e595eafdd7","_from":".","_npmVersion":"3.9.5","_nodeVersion":"6.2.2","_npmUser":{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"},"dist":{"shasum":"9798eab5e83be7b061b48908b08476e595eafdd7","tarball":"https://registry.npmjs.org/@aftonbladet/redux-api-middleware/-/redux-api-middleware-1.0.2-3.tgz","integrity":"sha512-FfvhuRffo/1duLx1XCX9jqJPT7S1pZ0XaaeiNY+kwfzo2AYq2OTEyGEqPWJ2QMysbyaw1lmuuAvDc4219/O6Dw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCBQLluH62liUQKrrHcRktYO+fKQ+apzQstfDXvxpmV9QIhAMBHFY8Yoz4xF2WN1z3T5VIDIFEcVztV0cn4yX+ikz/R"}]},"maintainers":[{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/redux-api-middleware-1.0.2-3.tgz_1473971018185_0.17427683132700622"}},"1.1.0":{"name":"@aftonbladet/redux-api-middleware","version":"1.1.0","description":"Redux middleware for calling an API.","main":"lib/index.js","scripts":{"build":"babel src --out-dir lib","clean":"rimraf lib coverage","cover":"babel-node ./node_modules/.bin/babel-istanbul cover test/index.js | tap-spec","lint":"eslint src test","prepublish":"npm run lint && npm test && npm run clean && npm run build","test":"babel-node test/index.js | tap-spec"},"repository":{"type":"git","url":"git+https://github.com/aftonbladet/redux-api-middleware.git"},"homepage":"https://github.com/Aftonbladet/redux-api-middleware","keywords":["redux","api","middleware","redux-middleware","flux"],"author":{"name":"Alberto Garcia-Raboso","email":"agraboso@gmail.com"},"license":"MIT","dependencies":{"babel-runtime":"^6","isomorphic-fetch":"^2.1.1","lodash.isplainobject":"^3.2.0"},"devDependencies":{"babel-cli":"^6","babel-eslint":"^6","babel-istanbul":"^0.3.20","babel-plugin-transform-runtime":"^6","babel-preset-es2015":"^6","babel-preset-stage-0":"^6","coveralls":"^2.11.4","eslint":"^1.6.0","eslint-plugin-babel":"^2.1.1","nock":"^2.15.0","normalizr":"^1.1.0","rimraf":"^2.4.3","tap-spec":"^4.1.0","tape":"^4.2.1"},"files":["README.md","LICENSE.md","lib/"],"gitHead":"4304fbb9700d3da3e4673c38986749ed81bc7e75","bugs":{"url":"https://github.com/aftonbladet/redux-api-middleware/issues"},"_id":"@aftonbladet/redux-api-middleware@1.1.0","_shasum":"fd717d424b33d7c30e1e53f7aebe80986c5c8b4e","_from":".","_npmVersion":"3.10.3","_nodeVersion":"6.6.0","_npmUser":{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"},"dist":{"shasum":"fd717d424b33d7c30e1e53f7aebe80986c5c8b4e","tarball":"https://registry.npmjs.org/@aftonbladet/redux-api-middleware/-/redux-api-middleware-1.1.0.tgz","integrity":"sha512-KzYx+hTCJF2HmdGx4dhwn4PJZ+jmXLR7sfIVC5AnKrOXHwyrYbuVDHNghE0IUsTHsNmaMxARQhGqwhJzHinOow==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDfjkEpsQuxNY55rZ9JhDBzU2rGFp5pQjwQ65zjRoVrxwIhAPetxlBB2cKPLDj/uaYypGBq2/AjknfuRm/wnFbizQyS"}]},"maintainers":[{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"},{"name":"stp.miroslaw.kucharzyk","email":"miroslaw.kucharzyk@schibsted.pl"}],"_npmOperationalInternal":{"host":"packages-18-east.internal.npmjs.com","tmp":"tmp/redux-api-middleware-1.1.0.tgz_1479910891816_0.8576860874891281"}},"1.1.1":{"name":"@aftonbladet/redux-api-middleware","version":"1.1.1","description":"Redux middleware for calling an API.","main":"lib/index.js","scripts":{"build":"babel src --out-dir lib","clean":"rimraf lib coverage","cover":"babel-node ./node_modules/.bin/babel-istanbul cover test/index.js | tap-spec","lint":"eslint src test","prepublish":"npm run lint && npm test && npm run clean && npm run build","test":"babel-node test/index.js | tap-spec"},"repository":{"type":"git","url":"git+https://github.com/Aftonbladet/redux-api-middleware.git"},"homepage":"https://github.com/Aftonbladet/redux-api-middleware","keywords":["redux","api","middleware","redux-middleware","flux"],"author":{"name":"Alberto Garcia-Raboso","email":"agraboso@gmail.com"},"license":"MIT","dependencies":{"babel-runtime":"^6","isomorphic-fetch":"^2.1.1","lodash.isplainobject":"^3.2.0"},"devDependencies":{"babel-cli":"^6","babel-eslint":"^6","babel-istanbul":"^0.3.20","babel-plugin-transform-runtime":"^6","babel-preset-es2015":"^6","babel-preset-stage-0":"^6","coveralls":"^2.11.4","eslint":"^1.6.0","eslint-plugin-babel":"^2.1.1","nock":"^2.15.0","normalizr":"^1.1.0","rimraf":"^2.4.3","tap-spec":"^4.1.0","tape":"^4.2.1"},"files":["README.md","LICENSE.md","lib/"],"gitHead":"8644bfaaed950f953932fe947f6caaee41633557","bugs":{"url":"https://github.com/Aftonbladet/redux-api-middleware/issues"},"_id":"@aftonbladet/redux-api-middleware@1.1.1","_shasum":"461ece66c89ff0f62892045d56b39d4ec6d71a23","_from":".","_npmVersion":"4.5.0","_nodeVersion":"6.9.4","_npmUser":{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"},"dist":{"shasum":"461ece66c89ff0f62892045d56b39d4ec6d71a23","tarball":"https://registry.npmjs.org/@aftonbladet/redux-api-middleware/-/redux-api-middleware-1.1.1.tgz","integrity":"sha512-djTo7fIwCSItlO+O5rwrZV9EZfOu9dh61AsvnGthudFwVifkJ8pIk79OXluO5XpfDOiqG8GF73eoVxrgyOL4qQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCare0Przn5tfZdNgkTZr/4L4LAKOACBrUV5W7HgZEIQwIhALzywBvnpSolFX3XoBZgAnzjuzTKQYxivtDdt0zyo/Z2"}]},"maintainers":[{"name":"aftonbladet","email":"tobias.jarlund@aftonbladet.se"},{"name":"stp.miroslaw.kucharzyk","email":"miroslaw.kucharzyk@schibsted.pl"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/redux-api-middleware-1.1.1.tgz_1494451096188_0.3090142966248095"}}},"readme":"redux-api-middleware\n====================\n\n[![Build Status](https://travis-ci.org/agraboso/redux-api-middleware.svg?branch=master)](https://travis-ci.org/agraboso/redux-api-middleware) [![Coverage Status](https://coveralls.io/repos/agraboso/redux-api-middleware/badge.svg?branch=master&service=github)](https://coveralls.io/github/agraboso/redux-api-middleware?branch=master)\n\n[Redux middleware](http://rackt.github.io/redux/docs/advanced/Middleware.html) for calling an API.\n\n## Table of contents\n\n1. [Introduction](#introduction)\n  - [A simple example](#a-simple-example)\n2. [Installation](#installation)\n3. [Usage](#usage)\n  - [Defining the API call](#defining-the-api-call)\n  - [Bailing out](#bailing-out)\n  - [Caching](#caching)\n  - [Lifecycle](#lifecycle)\n  - [Customizing the dispatched FSAs](#customizing-the-dispatched-fsas)\n4. [Reference](#reference)\n  - [Exports](#exports)\n  - [Flux Standard Actions](#flux-standard-actions)\n  - [Redux Standard API-calling Actions](#redux-standard-api-calling-actions)\n5. [History](#history)\n6. [Tests](#tests)\n7. [License](License)\n8. [Acknowledgements](#acknowledgements)\n\n## Introduction\n\nThis middleware receives [*Redux Standard API-calling Actions*](#redux-standard-api-calling-actions) (RSAAs) and dispatches [*Flux Standard Actions*](#flux-standard-actions) (FSAs) to the next middleware.\n\nRSAAs are identified by the presence of a `[CALL_API]` property, where [`CALL_API`](#call_api) is a `Symbol` defined in, and exported by `redux-api-middleware`. They contain information describing an API call and three different types of FSAs, known as the *request*, *success* and *failure* FSAs.\n\n### A simple example\n\nThe following is a minimal RSAA action:\n\n```js\nimport { CALL_API } from `redux-api-middleware`;\n\n{\n  [CALL_API]: {\n    endpoint: 'http://www.example.com/api/users',\n    method: 'GET',\n    types: ['REQUEST', 'SUCCESS', 'FAILURE']\n  }\n}\n```\n\nUpon receiving this action, `redux-api-middleware` will\n\n1. check that it is indeed a valid RSAA action;\n2. dispatch the following *request* FSA to the next middleware;\n\n    ```js\n    {\n      type: 'REQUEST'\n    }\n    ```\n\n3. make a GET request to `http://www.example.com/api/users`;\n4. if the request is successful, dispatch the following *success* FSA to the next middleware;\n\n    ```js\n    {\n      type: 'SUCCESS',\n      payload: {\n        users: [\n          { id: 1, name: 'John Doe' },\n          { id: 2, name: 'Jane Doe' },\n        ]\n      }\n    }\n    ```\n\n5. if the request is unsuccessful, dispatch the following *failure* FSA to the next middleware.\n\n    ```js\n    {\n      type: 'FAILURE',\n      payload: error // An ApiError object\n      error: true\n    }\n    ```\n\nWe have tiptoed around error-handling issues here. For a thorough walkthrough of the `redux-api-middleware` lifecycle, see [Lifecycle](#lifecycle) below.\n\n## Installation\n\n`redux-api-middleware` is available on [npm](https://www.npmjs.com/package/redux-api-middleware).\n\n```\n$ npm install redux-api-middleware --save\n```\n\nTo use it, wrap the standard Redux store with it. Here is an example setup. For more information (for example, on how to add several middlewares), consult the [Redux documentation](http://redux.js.org).\n\n#### configureStore.js\n\n```js\nimport { createStore, applyMiddleware, combineReducers } from 'redux';\nimport { apiMiddleware } from 'redux-api-middleware';\nimport reducers from './reducers';\n\nconst reducer = combineReducers(reducers);\nconst createStoreWithMiddleware = applyMiddleware(apiMiddleware)(createStore);\n\nexport default function configureStore(initialState) {\n  return createStoreWithMiddleware(reducer, initialState);\n}\n```\n\n#### app.js\n\n```js\nconst store = configureStore(initialState);\n```\n\n## Usage\n\n### Defining the API call\n\nThe parameters of the API call are specified by root properties of the `[CALL_API]` property of an RSAA.\n\n#### `[CALL_API].endpoint`\n\nThe URL endpoint for the API call.\n\nIt is usually a string, be it a plain old one or an ES2015 template string. It may also be a function taking the state of your Redux store as its argument, and returning such a string.\n\n####  `[CALL_API].method`\n\nThe HTTP method for the API call.\n\nIt must be one of the strings `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE` or `OPTIONS`, in any mixture of lowercase and uppercase letters.\n\n#### `[CALL_API].body`\n\nThe body of the API call.\n\n`redux-api-middleware` uses [`isomorphic-fetch`](https://github.com/matthew-andrews/isomorphic-fetch) to make the API call. `[CALL_API].body` should hence be a valid body according to the [fetch specification](https://fetch.spec.whatwg.org). In most cases, this will be a JSON-encoded string or a [`FormData`](https://developer.mozilla.org/en/docs/Web/API/FormData) object.\n\n#### `[CALL_API].headers`\n\nThe HTTP headers for the API call.\n\nIt is usually an object, with the keys specifying the header names and the values containing their content. For example, you can let the server know your call contains a JSON-encoded string body in the following way.\n\n```js\n{\n  [CALL_API]: {\n    ...\n    headers: { 'Content-Type': 'application/json' }\n    ...\n  }\n}\n```\n\nIt may also be a function taking the state of your Redux store as its argument, and returning an object of headers as above.\n\n#### `[CALL_API].options`\n\nThe fetch options for the API call. See [node-fetch](https://github.com/bitinn/node-fetch#options) for more information.\n\nIt is usually an object with the options keys/values. For example, you can specify a network timeout for node.js code\nin the following way.\n\n```js\n{\n  [CALL_API]: {\n    ...\n    options: { timeout: 3000 }\n    ...\n  }\n}\n```\n\nIt may also be a function taking the state of your Redux store as its argument, and returning an object of options as above.\n\n#### `[CALL_API].credentials`\n\nWhether or not to send cookies with the API call.\n\nIt must be one of the following strings:\n\n- `omit` is the default, and does not send any cookies;\n- `same-origin` only sends cookies for the current domain;\n- `include` always send cookies, even for cross-origin calls.\n\n### Bailing out\n\nIn some cases, the data you would like to fetch from the server may already be cached in you Redux store. Or you may decide that the current user does not have the necessary permissions to make some request.\n\nYou can tell `redux-api-middleware` to not make the API call through `[CALL_API].bailout`. If the value is `true`, the RSAA will die here, and no FSA will be passed on to the next middleware.\n\nA more useful possibility is to give `[CALL_API].bailout` a function. At runtime, it will be passed the state of your Redux store as its only argument, if the return value of the function is `true`, the API call will not be made.\n\n### Caching\n\nOften it is useful to be able to cache the API call being made to the server.\n\nYou can tell `redux-api-middleware` to use a cache through `[CALL_API].cache`. The value should point to an object implementing a cache API (see [`[CALL_API].cache`](#call_apicache)) with these three functions: `has` `get` and `set`.\n\n**NOTE** You will only be able to use a `[CALL_API].cache` API for endpoints returning JSON data.\n\nAn example cache implementation could look like this:\n\n```js\n{\n  [CALL_API]: {\n    ...\n    cache: {\n      has: (endpoint) => someCacheImplementation.has(endpoint),\n      async get(endpoint) {\n       // Returns cached data for endpoint\n       return someCacheImplementation.get(endpoint);\n      },\n      set(endpoint, jsonToCache) {\n       // Adds data to cache for key endpoint\n       someCacheImplementation.set(endpoint, jsonToCache);\n      }\n    }\n    ...\n  }\n}\n```\n\n### Lifecycle\n\nThe `[CALL_API].types` property controls the output of `redux-api-middleware`. The simplest form it can take is an array of length 3 consisting of string constants (or symbols), as in our [example](#a-simple-example) above. This results in the default behavior we now describe.\n\n1. When `redux-api-middleware` receives an action, it first checks whether it has a `[CALL_API]` property. If it does not, it was clearly not intended for processing with `redux-api-middleware`, and so it is unceremoniously passed on to the next middleware.\n\n2. It is now time to validate the action against the [RSAA definition](#redux-standard-api-calling-actions). If there are any validation errors, a *request* FSA will be dispatched (if at all possible) with the following properties:\n    - `type`: the string constant in the first position of the `[CALL_API].types` array;\n    - `payload`: an [`InvalidRSAA`](#invalidrsaa) object containing a list of said validation errors;\n    - `error: true`.\n\n  `redux-api-middleware` will perform no further operations. In particular, no API call will be made, and the incoming RSAA will die here.\n\n3. Now that `redux-api-middleware` is sure it has received a valid RSAA, it will try making the API call. If everything is alright, a *request* FSA will be dispatched with the following property:\n  - `type`: the string constant in the first position of the `[CALL_API].types` array.\n\n  But errors may pop up at this stage, for several reasons:\n  - `redux-api-middleware` has to call those of `[CALL_API].bailout`, `[CALL_API].endpoint` and `[CALL_API].headers` that happen to be a function, which may throw an error;\n  - `isomorphic-fetch` may throw an error: the RSAA definition is not strong enough to preclude that from happening (you may, for example, send in a `[CALL_API].body` that is not valid according to the fetch specification &mdash; mind the SHOULDs in the [RSAA definition](#redux-standard-api-calling-actions));\n  - a network failure occurs (the network is unreachable, the server responds with an error,...).\n\n  If such an error occurs, a different *request* FSA will be dispatched (*instead* of the one described above). It will contain the following properties:\n  - `type`: the string constant in the first position of the `[CALL_API].types` array;\n  - `payload`: a [`RequestError`](#requesterror) object containing an error message;\n  - `error: true`.\n\n4. If `redux-api-middleware` receives a response from the server with a status code in the 200 range, a *success* FSA will be dispatched with the following properties:\n  - `type`: the string constant in the second position of the `[CALL_API].types` array;\n  - `payload`: if the `Content-Type` header of the response is set to something JSONy (see [*Success* type descriptors](#success-type-descriptors) below), the parsed JSON response of the server, or undefined otherwise.\n\n  If the status code of the response falls outside that 200 range, a *failure* FSA will dispatched instead, with the following properties:\n  - `type`: the string constant in the third position of the `[CALL_API].types` array;\n  - `payload`: an [`ApiError`](#apierror) object containing the message `` `${status} - ${statusText}` ``;\n  - `error: true`.\n\n### Customizing the dispatched FSAs\n\nIt is possible to customize the output of `redux-api-middleware` by replacing one or more of the string constants (or symbols) in `[CALL_API].types` by a type descriptor.\n\nA *type descriptor* is a plain JavaScript object that will be used as a blueprint for the dispatched FSAs. As such, type descriptors must have a `type` property, intended to house the string constant or symbol specifying the `type` of the resulting FSAs.\n\nThey may also have `payload` and `meta` properties, which may be of any type. Functions passed as `payload` and `meta` properties of type descriptors will be evaluated at runtime. The signature of these functions should be different depending on whether the type descriptor refers to *request*, *success* or *failure* FSAs &mdash; keep reading.\n\nIf a custom `payload` and `meta` function throws an error, `redux-api-middleware` will dispatch an FSA with its `error` property set to `true`, and an `InternalError` object as its `payload`.\n\nA noteworthy feature of `redux-api-middleware` is that it accepts Promises (or function that return them) in `payload` and `meta` properties of type descriptors, and it will wait for them to resolve before dispatching the FSA &mdash; so no need to use anything like `redux-promise`.\n\n#### *Request* type descriptors\n\n`payload` and `meta` functions will be passed the RSAA action itself and the state of your Redux store.\n\nFor example, if you want your *request* FSA to have the URL endpoint of the API call in its `payload` property, you can model your RSAA on the following.\n\n```js\n// Input RSAA\n{\n  [CALL_API]: {\n    endpoint: 'http://www.example.com/api/users',\n    method: 'GET',\n    types: [\n      {\n        type: 'REQUEST',\n        payload: (action, state) => ({ endpoint: action.endpoint })\n      },\n      'SUCCESS',\n      'FAILURE'\n    ]\n  }\n}\n\n// Output request FSA\n{\n  type: 'REQUEST',\n  payload: { endpoint: 'http://www.example.com/api/users' }\n}\n```\n\nIf you do not need access to the action itself or the state of your Redux store, you may as well just use a static object. For example, if you want the `meta` property to contain a fixed message saying where in your application you're making the request, you can do this.\n\n```js\n// Input RSAA\n{\n  [CALL_API]: {\n    endpoint: 'http://www.example.com/api/users',\n    method: 'GET',\n    types: [\n      {\n        type: 'REQUEST',\n        meta: { source: 'userList' }\n      },\n      'SUCCESS',\n      'FAILURE'\n    ]\n  }\n}\n\n// Output request FSA\n{\n  type: 'REQUEST',\n  meta: { source: 'userList' }\n}\n```\n\nBy default, *request* FSAs will not contain `payload` and `meta` properties.\n\nError *request* FSAs might need to obviate these custom settings though.\n  - *Request* FSAs resulting from invalid RSAAs (step 2 in [Lifecycle](#lifecycle) above) cannot be customized. `redux-api-middleware` will try to dispatch an error *request* FSA, but it might not be able to (it may happen that the invalid RSAA does not contain a value that can be used as the *request* FSA `type` property, in which case `redux-api-middleware` will let the RSAA die silently).\n  - *Request* FSAs resulting in request errors (step 3 in [Lifecycle](#lifecycle) above) will honor the user-provided `meta`, but will ignore the user-provided `payload`, which is reserved for the default error object.\n\n#### *Success* type descriptors\n\n`payload` and `meta` functions will be passed the RSAA action itself, the state of your Redux store, and the raw server response.\n\nFor example, if you want to process the JSON response of the server using [`normalizr`](https://github.com/gaearon/normalizr), you can do it as follows.\n\n```js\nimport { Schema, arrayOf, normalize } from 'normalizr';\nconst userSchema = new Schema('users');\n\n// Input RSAA\n{\n  [CALL_API]: {\n    endpoint: 'http://www.example.com/api/users',\n    method: 'GET',\n    types: [\n      'REQUEST',\n      {\n        type: 'SUCCESS',\n        payload: (action, state, res) => {\n          const contentType = res.headers.get('Content-Type');\n          if (contentType && ~contentType.indexOf('json')) {\n            // Just making sure res.json() does not raise an error\n            return res.json().then((json) => normalize(json, { users: arrayOf(userSchema) }));\n          }\n        }\n      },\n      'FAILURE'\n    ]\n  }\n}\n\n// Output success FSA\n{\n  type: 'SUCCESS',\n  payload: {\n    result: [1, 2],\n    entities: {\n      users: {\n        1: {\n          id: 1,\n          name: 'John Doe'\n        },\n        2: {\n          id: 2,\n          name: 'Jane Doe'\n        }\n      }\n    }\n  }\n}\n```\n\nThe above pattern of parsing the JSON body of the server response is probably quite common, so `redux-api-middleware` exports a utility function `getJSON` which allows for the above `payload` function to be written as\n```js\n(action, state, res) => {\n  return getJSON(res).then((json) => normalize(json, { users: arrayOf(userSchema) }));\n}\n```\n\nBy default, *success* FSAs will not contain a `meta` property, while their `payload` property will be evaluated from\n```js\n(action, state, res) => getJSON(res)\n```\n\n#### *Failure* type descriptors\n\n`payload` and `meta` functions will be passed the RSAA action itself, the state of your Redux store, and the raw server response &mdash; exactly as for *success* type descriptors. The `error` property of dispatched *failure* FSAs will always be set to `true`.\n\nFor example, if you want the status code and status message of a unsuccessful API call in the `meta` property of your *failure* FSA, do the following.\n\n```js\n{\n  [CALL_API]: {\n    endpoint: 'http://www.example.com/api/users/1',\n    method: 'GET',\n    types: [\n      'REQUEST',\n      'SUCCESS',\n      {\n        type: 'FAILURE',\n        meta: (action, state, res) => {\n          if (res) {\n            return {\n              status: res.status\n              statusText: res.statusText\n            };\n          } else {\n            return {\n              status: 'Network request failed'\n            }\n          }\n        }\n      }\n    ]\n  }\n}\n```\nBy default, *failure* FSAs will not contain a `meta` property, while their `payload` property will be evaluated from\n```js\n(action, state, res) =>\n  getJSON(res).then(\n    (json) => new ApiError(res.status, res.statusText, json)\n  )\n```\n\n## Reference\n\n### Exports\n\nThe following objects are exported by `redux-api-middleware`.\n\n#### `CALL_API`\n\nA JavaScript `Symbol` whose presence as a key in an action signals that `redux-api-middleware` should process said action.\n\n#### `apiMiddleware`\n\nThe Redux middleware itself.\n\n#### `isRSAA(action)`\n\nA function that returns `true` if `action` has a `[CALL_API]` property, and `false` otherwise.\n\n#### `validateRSAA(action)`\n\nA function that validates `action` against the RSAA definition, returning an array of validation errors.\n\n#### `isValidRSAA(action)`\n\nA function that returns `true` if `action` conforms to the RSAA definition, and `false` otherwise. Internally, it simply checks the length of the array of validation errors returned by `validateRSAA(action)`.\n\n#### `InvalidRSAA`\n\nAn error class extending the native `Error` object. Its constructor takes an array of validation errors as its only argument.\n\n`InvalidRSAA` objects have three properties:\n\n- `name: 'InvalidRSAA'`;\n- `validationErrors`: the argument of the call to its constructor; and\n- `message: 'Invalid RSAA'`.\n\n#### `InternalError`\n\nAn error class extending the native `Error` object. Its constructor takes a string, intended to contain an error message.\n\n`InternalError` objects have two properties:\n\n- `name: 'InternalError'`;\n- `message`: the argument of the call to its constructor.\n\n#### `RequestError`\n\nAn error class extending the native `Error` object. Its constructor takes a string, intended to contain an error message.\n\n`RequestError` objects have two properties:\n\n- `name: 'RequestError'`;\n- `message`: the argument of the call to its constructor.\n\n#### `ApiError`\n\nAn error class extending the native `Error` object. Its constructor takes three arguments:\n\n- a status code,\n- a status text, and\n- a further object, intended for a possible JSON response from the server.\n\n`ApiError` objects have five properties:\n\n- `name: 'ApiError'`;\n- `status`: the first argument of the call to its constructor;\n- `statusText`: the second argument of the call to its constructor;\n- `response`: to the third argument of the call to its constructor; and\n- `` message : `${status} - ${statusText}` ``.\n\n#### `getJSON(res)`\n\nA function taking a response object as its only argument. If the response object contains a JSONy `Content-Type`, it returns a promise resolving to its JSON body. Otherwise, it returns a promise resolving to undefined.\n\n### Flux Standard Actions\n\nFor convenience, we recall here the definition of a [*Flux Standard Action*](https://github.com/acdlite/flux-standard-action).\n\nAn action MUST\n\n- be a plain JavaScript object,\n- have a `type` property.\n\nAn action MAY\n\n- have an `error` property,\n- have a `payload` property,\n- have a `meta` property.\n\nAn action MUST NOT\n\n- include properties other than `type`, `payload`, `error` and `meta`.\n\n#### `type`\n\nThe `type` of an action identifies to the consumer the nature of the action that has occurred. Two actions with the same `type` MUST be strictly equivalent (using `===`). By convention, `type` is usually a string constant or a `Symbol`.\n\n#### `payload`\n\nThe optional `payload` property MAY be any type of value. 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` field.\n\nBy convention, if `error` is true, the `payload` SHOULD be an error object. This is akin to rejecting a Promise with an error object.\n\n#### `error`\n\nThe optional `error` property MAY be set to `true` if the action represents an error.\n\nAn action whose `error` is true is analogous to a rejected Promise. By convention, the `payload` SHOULD be an error object.\n\nIf `error` has any other value besides `true`, including `undefined` and `null`, the action MUST NOT be interpreted as an error.\n\n#### `meta`\n\nThe optional `meta` property MAY be any type of value. It is intended for any extra information that is not part of the payload.\n\n### Redux Standard API-calling Actions\n\nThe definition of a *Redux Standard API-calling Action* below is the one used to validate RSAA actions. As explained in [Lifecycle](#lifecycle),\n  - actions without a `[CALL_API]` will be passed to the next middleware without any modifications;\n  - actions with a `[CALL_API]` property that fail validation will result in an error *request* FSA.\n\nA *Redux Standard API-calling Action* MUST\n\n- be a plain JavaScript object,\n- have a `[CALL_API]` property.\n\nA *Redux Standard API-calling Action* MUST NOT\n\n- include properties other than `[CALL_API]`.\n\n#### `[CALL_API]`\n\nThe `[CALL_API]` property MUST\n\n- be a plain JavaScript Object,\n- have an `endpoint` property,\n- have a `method` property,\n- have a `types` property.\n\nThe `[CALL_API]` property MAY\n\n- have a `body` property,\n- have a `headers` property,\n- have an `options` property,\n- have a `credentials` property,\n- have a `bailout` property.\n- have a `cache` property.\n\nThe `[CALL_API]` property MUST NOT\n\n- include properties other than `endpoint`, `method`, `types`, `body`, `headers`, `options`, `credentials`, `bailout` and `cache`.\n\n#### `[CALL_API].endpoint`\n\nThe `[CALL_API].endpoint` property MUST be a string or a function. In the second case, the function SHOULD return a string.\n\n#### `[CALL_API].method`\n\nThe `[CALL_API].method` property MUST be one of the strings `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE` or `OPTIONS`, in any mixture of lowercase and uppercase letters.\n\n#### `[CALL_API].body`\n\nThe optional `[CALL_API].body` property SHOULD be a valid body according to the [fetch specification](https://fetch.spec.whatwg.org).\n\n#### `[CALL_API].headers`\n\nThe optional `[CALL_API].headers` property MUST be a plain JavaScript object or a function. In the second case, the function SHOULD return a plain JavaScript object.\n\n#### `[CALL_API].options`\n\nThe optional `[CALL_API].options` property MUST be a plain JavaScript object or a function. In the second case, the function SHOULD return a plain JavaScript object.\nThe options object can contain any options supported by [node-fetch](https://github.com/bitinn/node-fetch#options).\n\n#### `[CALL_API].credentials`\n\nThe optional `[CALL_API].credentials` property MUST be one of the strings `omit`, `same-origin` or `include`.\n\n#### `[CALL_API].bailout`\n\nThe optional `[CALL_API].bailout` property MUST be a boolean or a function.\n\n#### `[CALL_API].cache`\n\nThe optional `[CALL_API].cache` property MUST be a plain JavaScript object implementing the functions `has`, `get` and `set`.\n\n##### `has(endpoint)`\nTakes an `endpoint` as its only argument. Should return `true` if the endpoint is in the cache and valid. Otherwise `false` should be returned.\n\n##### `get(endpoint)`\nTakes an `endpoint` as its only argument. Should return the cached result for the given endpoint.\n\n##### `set(endpoint, jsonToCache)`\nTakes an `endpoint` and the `jsonToCache` (the result of calling the endpoint) as its argument. The implementation should store the `jsonToCache` in the cache.\n\n#### `[CALL_API].types`\n\nThe `[CALL_API].types` property MUST be an array of length 3. Each element of the array MUST be a string, a `Symbol`, or a type descriptor.\n\n#### Type descriptors\n\nA type descriptor MUST\n\n- be a plain JavaScript object,\n- have a `type` property, which MUST be a string or a `Symbol`.\n\nA type descriptor MAY\n\n- have a `payload` property, which MAY be of any type,\n- have a `meta` property, which MAY be of any type.\n\nA type descriptor MUST NOT\n\n- have properties other than `type`, `payload` and `meta`.\n\n## History\n\nTODO\n\n## Tests\n\n```\n$ npm install && npm test\n```\n\n## License\n\nMIT\n\n## Projects using redux-api-middleware\n\n- [react-trebuchet](https://github.com/barrystaes/react-trebuchet/tree/test-bottledapi-apireduxmiddleware) (experimental/opinionated fork of react-slingshot for SPA frontends using REST JSON API backends)\n\nIf your opensource project uses (or works with) `redux-api-middleware` we would be happy to list it here!\n\n## Acknowledgements\n\nThe code in this module was originally extracted from the [real-world](https://github.com/rackt/redux/blob/master/examples/real-world/middleware/api.js) example in the [redux](https://github.com/rackt/redux) repository, due to [Dan Abramov](https://github.com/gaearon). It has evolved thanks to issues filed by, and pull requests contributed by, other developers.\n","maintainers":[{"email":"miroslaw.kucharzyk@schibsted.pl","name":"stp.miroslaw.kucharzyk"},{"email":"tobias.jarlund@aftonbladet.se","name":"aftonbladet"}],"time":{"modified":"2022-06-12T14:21:17.707Z","created":"2016-09-15T13:16:24.170Z","1.0.2-0":"2016-09-15T13:16:24.170Z","1.0.2-1":"2016-09-15T14:04:42.917Z","1.0.2-2":"2016-09-15T17:42:42.740Z","1.0.2-3":"2016-09-15T20:23:40.277Z","1.1.0":"2016-11-23T14:21:32.529Z","1.1.1":"2017-05-10T21:18:18.316Z"},"homepage":"https://github.com/Aftonbladet/redux-api-middleware","keywords":["redux","api","middleware","redux-middleware","flux"],"repository":{"type":"git","url":"git+https://github.com/Aftonbladet/redux-api-middleware.git"},"author":{"name":"Alberto Garcia-Raboso","email":"agraboso@gmail.com"},"bugs":{"url":"https://github.com/Aftonbladet/redux-api-middleware/issues"},"license":"MIT","readmeFilename":"README.md"}