{"id":13659101,"url":"https://github.com/jackfranklin/fetch-factory","last_synced_at":"2025-04-15T17:32:13.549Z","repository":{"id":34504342,"uuid":"38445357","full_name":"jackfranklin/fetch-factory","owner":"jackfranklin","description":"Easy JS objects for talking to your APIs","archived":false,"fork":false,"pushed_at":"2016-11-22T15:07:02.000Z","size":350,"stargazers_count":66,"open_issues_count":7,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-10T12:00:37.323Z","etag":null,"topics":[],"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/jackfranklin.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":"2015-07-02T16:56:33.000Z","updated_at":"2024-12-11T02:24:13.000Z","dependencies_parsed_at":"2022-09-06T04:11:33.230Z","dependency_job_id":null,"html_url":"https://github.com/jackfranklin/fetch-factory","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackfranklin%2Ffetch-factory","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackfranklin%2Ffetch-factory/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackfranklin%2Ffetch-factory/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackfranklin%2Ffetch-factory/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jackfranklin","download_url":"https://codeload.github.com/jackfranklin/fetch-factory/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249118800,"owners_count":21215622,"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","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":[],"created_at":"2024-08-02T05:01:05.288Z","updated_at":"2025-04-15T17:32:13.253Z","avatar_url":"https://github.com/jackfranklin.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# fetch-factory\n\nA wrapper around the new `fetch` API to make creating services to talk to APIs easier.\n\n## Example\n\n```js\nvar fetchFactory = require('fetch-factory');\n\nvar Users = fetchFactory.create({\n    url: 'http://api.mysite.com/users/:id',\n}, {\n    find: { method: 'GET' },\n    create: { method: 'POST' },\n});\n\nUsers.find(); // GET /users\n\nUsers.find({\n    params: { id: 123 },\n}); // GET /users/123\n\nUsers.create({\n    data: {\n        name: 'Jack',\n    },\n}); // POST /users with JSON stringified obj { name: 'jack' }\n```\n\nYou can run another example by cloning this repo and running `npm i \u0026\u0026 npm run example`.\n\n## Install\n\n```\nnpm install fetch-factory\n```\n\nConsumable in the client through jspm, Webpack or Browserify.\n\nYou can also grab `dist/fetch-factory.js` or `dist/fetch-factory.min.js` which is a browser build. It exposes `global.fetchFactory`. `example/index.html` shows how you would use this.\n\nNote that this library assumes a global `fetch` and `Promise` object. If you need to polyfill these, the following are recommended:\n\n- [github/fetch](https://github.com/github/fetch) `window.fetch` polyfill\n- [jakearchibald/es6-promise](https://github.com/jakearchibald/es6-promise) `Promise` polyfill.\n\n## Configuration\n\nConfiguration for a particular request can be set in one of three places:\n\n- in the config object that's the first argument to `fetchFactory.create`\n- in an object that you pass when telling fetch-factory what methods to create\n- in the call to the method that fetch factory created\n\nConfiguration set further down the chain will override configuration set previously. For example:\n\n```js\nvar UserFactory = fetchFactory.create({\n    url: 'http://api.mysite.com/users/:id',\n    method: 'GET',\n}, {\n    find: {},\n    create: { method: 'POST' },\n});\n```\n\nWhen `UserFactory.find` is called, it will make a `GET` request, because the default configuration for `UserFactory` was given `method: 'GET'`. However, when `UserFactory.create` is called, it will make a `POST` request, because configuration was passed that is specific to that method. Although in reality you never need to, you could call `UserFactory.find({ method: 'POST' })`, which would cause the `find` method to make a `POST` request that time, because configuration passed in when a method is invoked overrides any set before it.\n\n## POST Requests\n\nWhen a method defined by fetch-factory makes a `POST` request, it assumes that you'd like to POST JSON and sets some extra configuration:\n- the `Accept` header of the request is set to `application/json`\n- the `Content-Type` header of the request is set to `application/json`\n- if you pass in a `data` parameter, that is converted into JSON and sent as the body of the request\n\n## Shortcut Methods\n\nThere's a few methods that we've come to use often with our factories: `find`, `create` and `update`. fetch-factory comes with these definitions by default, so you can just tell it which ones you'd like to create:\n\n```js\nvar UserFactory = fetchFactory.create({\n    url: '/users/:id',\n    methods: ['find', 'create'],\n});\n```\n\n## Interceptors\n\nfetch-factory also supports the concept of interceptors that can take a request and manipulate it before passing it on.\n\n### Request Interceptors\n\nIf you need to apply a transformation to every request before it is made (for example, adding an authorisation header), you can use a request interceptor. These can be sync or async. You can define a single request interceptor, or an array of multiple. An interceptor is expected to return the modified request object, or a new object with three properties:\n\n- `headers`: an object of key value pairs mapping headers to values\n- `body`: the string representing the request body, or `null`.\n- `method`: the method of the request\n\n```js\nvar UserFactory = fetchFactory.create({\n    url: 'http://api.mysite.com/users/:id',\n    method: 'GET',\n    interceptors: {\n        request: function(request) {\n            request.headers['Authorisation']: 'Bearer ACCESS_TOKEN123';\n            return request;\n        },\n    },\n}, {\n    find: {},\n});\n\nUserFactory.find().then(function(data) {\n    console.log(data.name) // 'bob'\n});\n```\n\nBy using an interceptor in this way you can avoid repeating the authorisation logic accross your frontend code base.\n\n### Response Interceptors\n\nBy default, fetch-factory will call its default response interceptor:\n- It simply takes the stream returned by `fetch` and consumes it as JSON, returning a JavaScript object.\n\nYou can override this interceptor by passing an `interceptors` object with a `response` key:\n\n```js\nvar UserFactory = fetchFactory.create({\n    url: 'http://api.mysite.com/users/:id',\n    method: 'GET',\n    interceptors: {\n        response: function(data) {\n            return { name: 'bob' };\n        },\n    },\n}, {\n    find: {},\n});\n\nUserFactory.find().then(function(data) {\n    console.log(data.name) // 'bob'\n});\n```\n\nBy default, fetch-factory will call its default error handler.\n- It simply checks the status and rejects on any non-2xx status\n\nYou can disable the error handler by setting the `rejectOnBadResponse` flag to false. You can implement your own error handling logic. It is important that you handle response errors within the first passed `ìnterceptor`:\n\n```js\nvar UserFactory = fetchFactory.create({\n    url: 'http://api.mysite.com/users/:id',\n    method: 'GET',\n    rejectOnBadResponse: false,\n    interceptors: {\n        response: [\n            function(response) {\n                if (response.status \u003c 200 || response.status \u003e= 300) {\n                    const error = new Error(response.statusText);\n                    error.response = response;\n                    throw error;\n                }\n            },\n            function(data) {\n                return { name: 'bob' };\n            },\n        ],\n    },\n}, {\n    find: {},\n});\n\nUserFactory.find().catch(function(error) {\n    console.log(error.message)\n});\n```\n\nA time when you might want to override the default response interceptor is if you need access to extra information on the response, such as headers. In this case fetch-factory's default interceptor will be insufficient, and you should override it to simply pass the full request through:\n\n```js\nvar UserFactory = fetchFactory.create({\n    url: 'http://api.mysite.com/users/:id',\n    method: 'GET',\n    interceptors: {\n        response: function(response) { return response; },\n    },\n}, {\n    find: {},\n});\n\nUserFactory.find().then(function(response) {\n    console.log(response.headers.get('Content-Type'));\n});\n```\n\n\n\n## Changelog\n\n##### V0.2.1 - 8/12/2015\n- fix issue that lead to port numbers in URLs not working - thanks @copyhold\n\n##### V0.2.0 - 8/12/2015\n- fix isssue that lead to being unable to create more than one factory\n\n##### V0.1.0 - 11/11/2015\n- first release\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjackfranklin%2Ffetch-factory","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjackfranklin%2Ffetch-factory","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjackfranklin%2Ffetch-factory/lists"}