{"id":28921139,"url":"https://github.com/auru/unity-api","last_synced_at":"2025-08-03T16:40:31.869Z","repository":{"id":50095390,"uuid":"72122305","full_name":"auru/unity-api","owner":"auru","description":"REST-API helper, wrapped around fetch","archived":false,"fork":false,"pushed_at":"2021-06-04T11:26:00.000Z","size":383,"stargazers_count":13,"open_issues_count":18,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-19T03:17:31.906Z","etag":null,"topics":["api","api-rest","api-wrapper","fetch","middleware","rest","rest-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/auru.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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-10-27T15:32:13.000Z","updated_at":"2022-04-02T08:51:47.000Z","dependencies_parsed_at":"2022-08-03T19:00:13.173Z","dependency_job_id":null,"html_url":"https://github.com/auru/unity-api","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/auru/unity-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/auru%2Funity-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/auru%2Funity-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/auru%2Funity-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/auru%2Funity-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/auru","download_url":"https://codeload.github.com/auru/unity-api/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/auru%2Funity-api/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261154004,"owners_count":23116949,"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":["api","api-rest","api-wrapper","fetch","middleware","rest","rest-api"],"created_at":"2025-06-22T06:07:15.564Z","updated_at":"2025-08-03T16:40:31.844Z","avatar_url":"https://github.com/auru.png","language":"JavaScript","readme":"# Unity API\n\n[![Travis-CI](https://api.travis-ci.org/auru/unity-api.svg?branch=master)](https://travis-ci.org/auru/unity-api)\n[![Coverage Status](https://coveralls.io/repos/github/auru/unity-api/badge.svg?branch=master)](https://coveralls.io/github/auru/unity-api?branch=master)\n[![npm version](https://badge.fury.io/js/unity-api.svg)](https://badge.fury.io/js/unity-api)\n[![Scrutinizer](https://scrutinizer-ci.com/g/auru/unity-api/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/auru/unity-api/)\n[![Deps](https://david-dm.org/auru/unity-api/status.svg)](https://david-dm.org/auru/unity-api)\n[![Deps-Dev](https://david-dm.org/auru/unity-api/dev-status.svg)](https://david-dm.org/auru/unity-api)\n[![Dependency Status](https://dependencyci.com/github/auru/unity-api/badge)](https://dependencyci.com/github/auru/unity-api)\n\n\u003e REST-API helper, wrapped around `fetch`.\n\n# Table of Contents\n\n* [Installation](#installation)\n* [API](#api)\n* [Usage](#usage)\n* [Example](#example)\n* [Contributing](#contributing)\n* [License](#license)\n\n# Installation\n\n```bash\nnpm i --save unity-api\n```\n\n# API\n## createAPI(resources, middleware, namespace, cancelNamespace);\n\n**Returns:** {Object}\n\nUse module's `default export` to create an API object.\n\n### resources {Object} *Optional*\n\nAn API would be redundant without any of resources defined. \n\nEach resource represents an entity in your REST-API as an `object` with the following properties:\n\n#### namespace {String} *Optional*\n\nNamespace of an entity. *e.g.*: example.com/api/**user**/get\n\n#### methods {Object}\n\nDictionary of facade-methods that transform your api calls params to `fetch` calls params.\nEach method should return a plain `object` with the following properties:\n\n##### path {Array|String} *Optional*\n**Default:** `''`\n\nIf path is an `array`, items will be joined and normalized.\n\n##### query {Object} *Optional*\n**Default:** `{}`\n\nQuery-like object.\n\n##### options {Object} *Optional*\n**Default:** `{}`\n\n`fetch` [options](https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch#Parameters).\n\n##### type {string} *Optional*\n**Default:** `'json'`\n\n**Alias:** `method`\n\nType of reponse data / method to be called on `fetch`'s response (ex: `'json'`, `'text'`, `'blob'`) \n\n##### headers {Object|Headers}\n\nAdditional headers to be sent to the server\n\n##### body {string|FormData}\n\nRequests's body\n\n\nAlternatively you can use provided shortcuts for [every HTTP method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods)\n\n**Example:**\n```js\nimport { GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH } from 'unity-api';\n\nconst userResource = {\n  namespace: 'user',\n\n  methods: {\n    // id = 1, extanted = true\n    // GET: /api/user/1?extended=true\n    get: ({ id, extended }) =\u003e ({ path: [id], query: { extended: !!extended } }),\n\n    // POST: /api/user/1/edit\n    save: ({ id, firstname, lastname }) =\u003e {\n        const formData = new FormData();\n\n        formData.append('firstname', firstname);\n        formData.append('lastname', lastname);\n\n        return POST({\n            path: [id, 'edit'],\n            headers: { 'x-csrf-token': 'blah' }\n            body: formData\n        });\n    },\n\n    // DELETE: /api/user/1\n    delete: ({ id }) =\u003e DELETE({ path: [id] })\n  }\n}\n```\n\n### middleware {Array} of {Function} *Optional*\n\nAn array of middleware functions, that can manipulate an api call, its params and its result, along with options for the remaning middleware in chain.\n\n```js \nconst myMiddleware = next =\u003e async (options, params, resource, method) =\u003e { return await next() }\n```\n#### next {Function}\n\nAn `async` function, that calls next middleware in chain, or, in case of last middleware, the api method itself.\n\n#### options {Object} *Optional*\n\nMiddleware parameters, that an api call was made with.\n\n#### params {Object} *Optional*\n\nParameters, that an api call was made with.\n\n#### resource {String} *Optional*\n\nName of the resource, whose method was called.\n\n#### method {String} *Optional*\n\nName of the method called\n\n**Example logger middleware:**\n```js\nexport default next =\u003e async (middlewareOptions, apiCallParams, resource, method) =\u003e {\n    console.log('args', { middlewareOptions, apiCallParams, resource, method }); // eslint-disable-line no-console\n    const result = await next();\n    console.log('result', result); // eslint-disable-line no-console\n    return result;\n};\n```\n\n### namespace {String} *Optional*\n\n**Default:** `'api'`\n\nUsually you would want to proxy api calls from the SPA to the backend using some common namespace. *e.g.* example.com/**api**/user/get\n\n### cancelNamespace {String} *Optional*\n\n**Default:** `'cancel'`\n\n```js\nconst promise = API.example.get();\n\npromise.cancel();\n```\n\nUsually you would want to cancel api calls. This is the name of the cancel method.\n\n# Usage\n\nYou can call your API methods like so: \n`API[resource][method](methodParams, middlewareOptions)`\n\n# Example\n\nCreate API module:\n\n```js\n// api.js\nimport createAPI from 'unity-api';\n\nconst resources = {\n  user: {\n    namespace: 'user',\n    methods: {\n      get: ({ id }) =\u003e ({ path: id }),\n      delete: ({ id }) =\u003e ({ path: id, options: { method: 'DELETE' } }),\n      getAsText: ({ id }) =\u003e ({ path: id, type: 'text' }),\n    }\n  }\n}\n\nconst logger = next =\u003e async (middlewareOptions, apiCallParams, resource, method) =\u003e {\n    const { log } = middlewareOptions;\n    \n    if (log) {\n       console.log('args', { middlewareOptions, apiCallParams, resource, method }); // eslint-disable-line no-console\n    }\n    \n    const result = await next();\n    \n    if (log) {\n       console.log('result', result); // eslint-disable-line no-console\n    }\n    \n    return result;\n};\n\nconst middleware = [\n  logger\n]\n\nconst API = createAPI(resources, middleware, 'api', 'cancel');\n\nexport default API;\n```\n\nUse it in your application:\n\n```js\n// index.js\nimport API from './api';\n\nconst user = await API.user.get({ id: 1 }, { log: true });\n\n```\n\n# Contributing\n\n* Provide [conventional commit messages](https://github.com/conventional-changelog/conventional-changelog-angular/blob/master/convention.md) by using `npm run commit` instead of `git commit`.\n* **Core contributors:** use GitHub's *Rebase and merge* as a default way of merging PRs.\n\n# License\nMIT © AuRu\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fauru%2Funity-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fauru%2Funity-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fauru%2Funity-api/lists"}