{"id":15357225,"url":"https://github.com/gera2ld/restful-fetch","last_synced_at":"2025-04-15T06:42:51.304Z","repository":{"id":57355030,"uuid":"56318653","full_name":"gera2ld/restful-fetch","owner":"gera2ld","description":"Restful APIs based on isomorphic-fetch","archived":false,"fork":false,"pushed_at":"2017-02-28T14:35:08.000Z","size":99,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-15T06:42:46.171Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/gera2ld.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":"2016-04-15T12:31:42.000Z","updated_at":"2019-06-22T03:44:16.000Z","dependencies_parsed_at":"2022-08-28T13:20:45.823Z","dependency_job_id":null,"html_url":"https://github.com/gera2ld/restful-fetch","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gera2ld%2Frestful-fetch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gera2ld%2Frestful-fetch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gera2ld%2Frestful-fetch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gera2ld%2Frestful-fetch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gera2ld","download_url":"https://codeload.github.com/gera2ld/restful-fetch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249023727,"owners_count":21199958,"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-10-01T12:34:05.940Z","updated_at":"2025-04-15T06:42:51.280Z","avatar_url":"https://github.com/gera2ld.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# restful-fetch\n\n![NPM](https://img.shields.io/npm/v/restful-fetch.svg)\n![License](https://img.shields.io/npm/l/restful-fetch.svg)\n![Downloads](https://img.shields.io/npm/dt/restful-fetch.svg)\n\nA RESTful library based on [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch).\n\n## Installation\n\n``` sh\n$ npm i restful-fetch\n```\n\n## Quick start\n\n``` js\nimport Restful from 'restful-fetch';\n\nconst restful = new Restful();\n\nconst Foo = restful.model('foo');\nFoo.get().then(data =\u003e console.log(data));    // GET /foo\n\nFoo.Single = Foo.model(':id');\nFoo.Single.fill({id: 1}).get().then(data =\u003e console.log(data));   // GET /foo/1\n\nFoo.Bar = Foo.Single.model('bar');\nFoo.Bar.fill({id: 1}).get().then(data =\u003e console.log(data));      // GET /foo/1/bar\n```\n\n## Documents\n\n### Overview\n\nEverything is a model, derives from models and derives models.\n\n![restful-fetch](static/restful-fetch.png)\n\n### Restful\n\nA `Restful` instance is the root model, which has a few properties to be shared\nby all its derivatives. The properties are:\n\n* `prehandlers`\n* `posthandlers`\n* `errhandlers`\n\nThe handlers will be discussed more as **interceptors**.\n\n**Parameters**\n\n* **options**: *(Optional) Object*\n\n  * root: *(Optional) String*\n\n    Base address for all requests, default as `''`.\n\n  * headers: *(Optional) Object*\n\n    Default request headers.\n\n  * config: *(Optional) Object*\n\n    Extra config to be passed to [fetch](https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch).\n\n  * methods: *(Optional) Object*\n\n    Custom methods to be bound to models. The object are composed of `methodName: methodInfo` pairs.\n    `methodInfo` may have following properties:\n\n    * `method`\n\n      The HTTP method to be used for requests, default as `GET`.\n\n    * `args`\n\n      The argument name list. Names may be `url`, `params`, `body` and `headers`.\n\n  ``` js\n  const restful = new Restful({\n    root: '/api',\n    headers: {\n      'X-From': 'restful-fetch',\n    },\n    methods: {\n      foo: {\n        method: 'GET',\n        args: ['url', 'params']\n      }\n    }\n  });\n\n  // restful.foo(url, params)\n  ```\n\n**Methods**\n\nAn `Restful` instance has all methods that a derived model has, except for `fill`,\nwhich should only work in abstract models.\n\n``` js\nconst restful = new Restful(options);\n// or\nconst restful = Restful(options);\n```\n\n**Notes**\n\n\u003e A Restful instance should be a singleton and used all over the project.\n\u003e The options will be handled and can be reached and modified by `restful.options`.\n\n### Model\n\nA `Model` instance is an object derived from a `Restful` instance or another model.\n\nA model instance has following properties:\n\n* `prehandlers`\n* `posthandlers`\n* `overrides`\n\nThe handlers will be discussed more as **interceptors**.\n\n**Methods**\n\n* model(...args: *[]String*)\n\n  Derive a submodel.\n\n  A model is always generated by `instance.model(...args)`.\n  Each argument is a part of URL and will be joined with `/` as the submodel's relative path.\n\n  If a part of URL starts with `:`, it will be marked as a **placeholder**.\n  Models with placeholders are abstract models, and can not make requests\n  directly. Abstract models have to be `fill`ed with data to get non-abstract\n  models before making requests. This is designed to share properties between\n  different model instances.\n\n* fill(data: *Object*)\n\n  Derive a new `Model` instance with placeholders filled with `data`.\n  `data` is an object with keys as the placeholder names and values to be filled with.\n\n* request(options: *Object*)\n\n  A low-level request method called by `get`, `post`, `put`, etc. `options` may have\n  following properties:\n\n  * url: *String*, default as `''`\n  * method: *String*, default as `GET`\n  * headers: *Object*, default as `null`\n  * params: *Object*, default as `null`\n  * body: *Any*, default as `null`\n\n* post(url: *String*, data: *Any*, params: *(Optional) Object*)\n\n  `POST` request.\n\n* get(url: *String*, params: *(Optional) Object*)\n\n  `GET` request.\n\n* put(url: *String*, data: *Any*, params: *(Optional) Object*)\n\n  `PUT` request.\n\n* patch(url: *String*, data: *Any*, params: *(Optional) Object*)\n\n  `PATCH` request.\n\n* delete(url: *String*, params: *(Optional) Object*)\n\n  `DELETE` request.\n\n``` js\nconst Cars = restful.model('cars');\n\nconst AbstractCar = restful.model('cars', ':id');\n// or\nconst AbstractCar = Cars.model(':id');\n\nAbstractCar.prehandlers.push(function () {\n  console.log('Get a car!');\n});\n\nconst car1 = AbstractCar.fill({id: 1});\nconst car2 = AbstractCar.fill({id: 2});\n\nconst seats = car1.model('seats');\nseats.get().then(data =\u003e console.log(data));\n```\n\n### Interceptors\n\n`Restful` and `Model` instances have a several handler properties, which contains\nlists of interceptors.\nThose on `Restful` instances are global interceptors and those on `Model` instances\nare model specific interceptors.\n\n* `prehandlers` (present on `Restful` and `Model`)\n\n  Process order: `Model::prehandlers -\u003e Restful::prehandlers`.\n\n  Each prehandler is called with one parameter: the request options. Returned value\n  will be merged into it, so only the changed attributes need to be returned.\n\n* `posthandlers` (present on `Restful` and `Model`)\n\n  Process order: `Restful::posthandlers -\u003e Model::posthandlers`.\n\n  Each posthandler is called with two parameters: `data, options`. `data` is the\n  current data object and can be modified by returning a new one. `options` contains\n  all information of the request, including `method`, `url` (full url), `relative`\n  (url relative to current model).\n\n  There are two default posthandlers on a Restful object so that you may either\n  resolve the response data or reject an object with the response object and its data:\n\n    - `response =\u003e ({response, data})`\n    - `({response, data}) =\u003e response.ok ? data : reject({response, data})`\n\n* `errhandlers` (present on `Restful`)\n\n  Each errhandler is called with the error captured.\n  The last errhandler should throw the error to make a rejection to the promise.\n\n* `overrides` (present on `Model`)\n\n  Overrides global handlers on `Restful` object for current model.\n\n```js\nconst restful = new Restful();\nconst model = restful.model('/cars/1');\n\n// Global interceptors will be processed for all requests\nrestful.prehandlers.push(options =\u003e {\n  return {\n    params: Object.assign({}, options.params, {hello: 'world'}),\n  };\n});\nrestful.posthandlers.push(res =\u003e {\n  console.log('Intercepted:', res);\n  return res;\n});\n\n// Model interceptors will be processed only for the model itself\n// Model prehandlers will execute BEFORE global prehandlers\nmodel.prehandlers.push(options =\u003e {\n  return {\n    headers: {\n      'X-From-Model': true,\n    },\n  };\n});\n// Model posthandlers will be processed AFTER global posthandlers\nmodel.posthandlers.push(data =\u003e {\n  return data || 'empty';\n});\n\nmodel.overrides = {\n  posthandlers: [],   // disable global posthandlers\n};\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgera2ld%2Frestful-fetch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgera2ld%2Frestful-fetch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgera2ld%2Frestful-fetch/lists"}