{"id":24344173,"url":"https://github.com/klooperator/redux-rest-fetcher","last_synced_at":"2026-04-15T10:31:54.153Z","repository":{"id":57351381,"uuid":"117692454","full_name":"klooperator/redux-rest-fetcher","owner":"klooperator","description":"Create and save fetch calls to redux store","archived":false,"fork":false,"pushed_at":"2018-05-06T22:42:26.000Z","size":106,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-25T14:11:07.573Z","etag":null,"topics":["fetch","fetch-api","fetcher","javascript","react","react-native","redux","rest-api","restful-api"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/klooperator.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-16T14:16:41.000Z","updated_at":"2018-05-06T22:42:27.000Z","dependencies_parsed_at":"2022-08-31T03:53:33.838Z","dependency_job_id":null,"html_url":"https://github.com/klooperator/redux-rest-fetcher","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/klooperator/redux-rest-fetcher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klooperator%2Fredux-rest-fetcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klooperator%2Fredux-rest-fetcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klooperator%2Fredux-rest-fetcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klooperator%2Fredux-rest-fetcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/klooperator","download_url":"https://codeload.github.com/klooperator/redux-rest-fetcher/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klooperator%2Fredux-rest-fetcher/sbom","scorecard":{"id":563588,"data":{"date":"2025-08-18","repo":{"name":"github.com/klooperator/redux-rest-fetcher","commit":"5e1c6ae22bd17ffa9a1b1c8e3048e7f90c36719a"},"scorecard":{"version":"v5.2.1-41-g40576783","commit":"40576783fda6698350fcbbeaea760ff827433034"},"score":1.3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#dangerous-workflow"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#fuzzing"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"47 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-vh7m-p724-62c2","Warn: Project is vulnerable to: GHSA-r9p9-mrjm-926w","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488","Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g","Warn: Project is vulnerable to: GHSA-4xc9-xhrj-v574","Warn: Project is vulnerable to: GHSA-x5rq-j2xg-h7qm","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-xf5p-87ch-gxw2","Warn: Project is vulnerable to: GHSA-5v2h-r2cx-5xgj","Warn: Project is vulnerable to: GHSA-rrrm-qjm4-v8hf","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-mxhp-79qh-mcx6","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-662x-fhqg-9p8v","Warn: Project is vulnerable to: GHSA-394c-5j6w-4xmx","Warn: Project is vulnerable to: GHSA-78cj-fxph-m83p","Warn: Project is vulnerable to: GHSA-fhg7-m89q-25r3","Warn: Project is vulnerable to: GHSA-cf4h-3jhx-xvhq"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T14:20:18.157Z","repository_id":57351381,"created_at":"2025-08-20T14:20:18.157Z","updated_at":"2025-08-20T14:20:18.157Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28000524,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-24T02:00:07.193Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fetch","fetch-api","fetcher","javascript","react","react-native","redux","rest-api","restful-api"],"created_at":"2025-01-18T09:22:47.479Z","updated_at":"2025-12-24T10:16:29.441Z","avatar_url":"https://github.com/klooperator.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-redux-fetcher\n\n**This library was made for my personal project. Not all use cases are tested. I welcome testers, sugestions, pull requests etc.**\n\nSmall library for creating API endpoint calls and other fetch calls. Can be used in any project, but is meant to be used with redux to dispatch results to store.\n\nSmall, treeshaked lodash dependency.\n\nOriginal at: [https://github.com/klooperator/redux-rest-fetcher](https://github.com/klooperator/redux-rest-fetcher)\n\n## Install\n\n```\nnpm install redux-rest-fetcher --save\n```\n```\nyarn add redux-rest-fetcher\n```\n```\nbower install redux-rest-fetcher --save\n```\n\n## Description \u0026 example\n\nThis library is influenced by [redux-api](https://github.com/lexich/redux-api), but instead od using FLUX architecture it will put all its calls under one named reducer.\n\nOnce setup you can create your calls like this:\n\n```javascript\n    calls = {\n         login:{\n            url: \"http://yoursite.com/api/login\",\n            method: 'post',\n            headers:{\n                Accept: 'application/json'\n                }\n         },\n         getUser:{\n            url: \"http://yoursite.com/api/get-user/:id\",\n           method: 'get',\n           headers:{\n                Accept: 'application/json'\n                }\n        },\n    }\n```\n\nAfter that you just make a call like this:\n\n```javascript\n    Api.login({body: logindata});\n    Api.getUser({id: userID})\n```\n\n## Configuration\n\nTo configure it properly you should call an instance of it in you app entry point, right before you create a global store instance.\n\n```javascript\nimport React from 'react';\nimport { render } from 'react-dom';\nimport { Provider } from 'react-redux';\nimport api from 'redux-rest-fetcher';\nimport apiCalls from './src/api/calls';\n\n//here you can setup basic configuration that will be valid for all calls.\napi.setBaseUrl('http://your-restapi-adress.com');\n//you can ommit this, but in case you use other fetch (ex. polyfill) you can set it here\napi.setFetch(window.fetch);\n//also can be ommited, default is 'api(.)(.)'\n//you will see this in redux actions: api(.)(.)callName\napi.setPrefix('api@@');\n//and of course api calls\napi.setEndpoints(apiCalls);\n```\nAt this point redux-rest-fetcher is ready to be passed to your store. Extract reducer from it\n```javascript\nconst apiReducer = api.getReducer()\n```\nand pass it to your store to be incorporated in your ```combineReducer()```\n```javascript\nconst rootReducer = combineReducer({\n\tsomething,\n\tapiReducer,\n\tsomethingElse\n});\n```\nOnce your store is created and populated with ```@@INIT```, pass a dispatcher to api.\n\n```javascript\napi.setDispatcher(store.dispatch)\n```\nNow any time you call you api calls, results will be placed to redux store.\n\n## Creating calls\n\nYou create your calls as key value object pairs. Where key will be a name of the function you call and value the call options.\nYo can create multiple files, for ex. each for specific endpoint of your api\n\n```javascript\n// /calls/User.js\nconst enpoint = 'user';\nexport default {\n    login:{\n        url: `${endpoint}/login`,\n        options: {\n            method: 'post',\n            headers:{\n                accept: 'application/json',\n                }\n            },\n    },\n    getGender:{\n        url: `${endpoint}/gender/:id`,\n        options: {\n            headers:{\n                Accept: \"text/html\",\n                \"Content-Type\": \"text/html;charset=utf-8\",\n                }\n            },\n    }\n}\n...\n// calls/server.js\nconst enpoint = 'server';\nexport default {\n    refresh:{\n        url: `${endpoint}/refresh`,\n        options: {\n            credentials: 'omit',\n            headers:{\n                accept: 'application/json',\n\n                }\n            },\n    },\n}\n...\n// calls/index.js\nimport User from './User';\nimport Srv from './Server';\nconst calls = Object.assign({}, User, Srv);\nexport default calls;\n```\n\n## Overrides and more overrides\n\nThere are 3 levels of constructing your request. Base options, options inside your calls and per call options.\n\nFirstly you can set base options. If no other options are set this will be used for each call. In next example we will just implement default options ( this are already in there, if you skip this step, those will be your base options)\n\n```javascript\napi.setBaseOptions({\n      credentials: \"include\",\n      headers: {\n        Accept: \"application/json\",\n        \"Content-Type\": \"application/json\",\n        Cache: \"no-cache\",\n        credentials: \"same-origin\"\n      }\n    })\n```\n\nThen you can override base options with options in call object.In example for ```refresh``` resulting options will be:\n```javascript\n{\n      credentials: \"include\",\n      headers: {\n        Accept: \"text/html\",\n        \"Content-Type\": \"text/html;charset=utf-8\",\n        Cache: \"no-cache\",\n      }\n    }\n```\nIn the end you can override request per call by passing second paramater object with desired vaue like this:\n```javascript\napi.refresh({},{\n    headers:{\n        Cache: 'force-cache'\n        }\n    });\n//result:\n{\n      credentials: \"include\",\n      headers: {\n        Accept: \"text/html\",\n        \"Content-Type\": \"text/html;charset=utf-8\",\n        Cache: \"force-cache\",\n      }\n    }\n```\n### Overiding URL\n\nDuring your basic configuration you can setup base URL that will be attached to every call as prefix.\n```javascript\napi.setBaseUrl('localhost:3030');\n```\nDefult base URL is empty string, so all calls will be made on same page.\nYou can override URL on the flight with absolute ```url``` key. Redux-rest-fetcher will check if ```url``` has ```'http'```, and if yes it will not attach baseUrl prefix to that call.\n```javascript\nexport default = {\n\tsomeService:{\n\t\turl:'http://someservice.com/api'//this will override baseUrl\n\t}\n}\n```\n## Features\nThere are several features included.\n#### Body parsing\nYou can send either stringified JSON or plain object to your call.\n```javascript\napi.login({body: obj});\n//same as\napi.login({body: JSON.stringify(obj)});\n```\n####  GET params\nYou can past your get params as object with key ```GET```. It will be parsed and the result will be attached to your call URL.\n```javascript\napi.someService({\n    GET:{\n        serial: '123456',\n        foo: 'bar'\n    }\n});\n// end url result:\n'http://someservice.com/api?serial=123456\u0026foo=bar'\n```\n#### expected\nYou can set what you expect to as return to prevent fetch errors before they occur.\n\nDefault expect is ```json```.\n```javascript\napi.getText({expected: 'text'})\n```\n\u003eOf course that means ```body```, ```GET``` and ```expected``` are reserved and do not make keys in url params with those keywords (```url/api/:GET``` or ```uer/api/:body```)\n## Using without redux\nYou can use this library without redux. If you don't pass dispatch function to the library instance you will receive a fetch promise that you need to resolve yourself.\n## Roadmap\n\n1. Test sending formData, files and other non JSON cases\n2. Add postfetch tranformer methods like:\n    * add to array\n    * soft data update\n3. Resolve loading flag to be per call and as pool globaly\n4. Remove lodash dependency\n5. Fix rollup setup\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklooperator%2Fredux-rest-fetcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fklooperator%2Fredux-rest-fetcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklooperator%2Fredux-rest-fetcher/lists"}