{"id":18789609,"url":"https://github.com/joelalejandro/feathers-hooks-jsonapify","last_synced_at":"2025-04-13T14:06:11.837Z","repository":{"id":51789401,"uuid":"88313539","full_name":"joelalejandro/feathers-hooks-jsonapify","owner":"joelalejandro","description":"Feathers hook for outputting data in a JSON-API-compliant way.","archived":false,"fork":false,"pushed_at":"2021-05-10T00:20:14.000Z","size":25,"stargazers_count":12,"open_issues_count":9,"forks_count":6,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-27T05:02:56.169Z","etag":null,"topics":["feathers-hook","json-api-serializer"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joelalejandro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-15T00:40:16.000Z","updated_at":"2021-05-21T19:22:54.000Z","dependencies_parsed_at":"2022-09-04T21:26:06.717Z","dependency_job_id":null,"html_url":"https://github.com/joelalejandro/feathers-hooks-jsonapify","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joelalejandro%2Ffeathers-hooks-jsonapify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joelalejandro%2Ffeathers-hooks-jsonapify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joelalejandro%2Ffeathers-hooks-jsonapify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joelalejandro%2Ffeathers-hooks-jsonapify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joelalejandro","download_url":"https://codeload.github.com/joelalejandro/feathers-hooks-jsonapify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248681568,"owners_count":21144709,"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":["feathers-hook","json-api-serializer"],"created_at":"2024-11-07T21:08:04.127Z","updated_at":"2025-04-13T14:06:11.815Z","avatar_url":"https://github.com/joelalejandro.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# feathers-hooks-jsonapify\nFeathers hook for outputting data in a JSON-API-compliant way.\n\n_Currently works great with **Sequelize** as an adapter. There are plans to support more adapters in the future._\n\n[![npm version](https://badge.fury.io/js/feathers-hooks-jsonapify.svg)](https://www.npmjs.com/package/feathers-hooks-jsonapify)\n\n## Installing\n\nSimply run `npm install --save feathers-hooks-jsonapify` and you're good to go!\n\n## Usage\n\nThis hook is intended to use with `feathers-rest`, since it'll convert that provider's response to a JSON-API compliant document.\n\nRequire the hook:\n\n```js\nconst jsonapify = require('feathers-hooks-jsonapify');\n```\n\nThen choose how to implement it.\n\n### Tied up to a service\n\n```js\napp.service('messages').hooks({\n  after: {\n    find: [ jsonapify() ],\n    get: [ jsonapify() ]\n  }\n});\n```\n\n### As a global hook\n\n```js\napp.hooks({\n  after: {\n    find: [ jsonapify() ],\n    get: [ jsonapify() ]\n  }\n});\n```\n\n### Relationships\n\n*Available since: `v0.1.4`*\n\n`feathers-hooks-jsonapify` will automatically detect metadata for relationships in the model. It'll create an `included` top-level array in the document when the hook is called via `find`.\n\n\u003e Currently working and tested with `belongsTo` and `hasMany` associations. This feature works only with a Sequelize adapter.\n\n#### Example document for a self-referencing model\n\n```json\n{\n  \"data\": {\n    \"type\": \"topics\",\n    \"id\": \"sports-cars\",\n    \"attributes\": {\n      \"name\": \"Cars\",\n      \"created-at\": \"2017-04-14T22:22:03.000Z\",\n      \"updated-at\": null\n    },\n    \"relationships\": {\n      \"parent-topic\": {\n        \"data\": {\n          \"type\": \"topics\",\n          \"id\": \"sports\"\n        }\n      }\n    },\n    \"links\": {\n      \"self\": \"/topics/sports-cars\",\n      \"parent\": \"/topics\"\n    }\n  },\n  \"included\": [\n    {\n      \"type\": \"topics\",\n      \"id\": \"sports\",\n      \"attributes\": {\n        \"name\": \"Sports\",\n        \"parent-topic-id\": null,\n        \"created-at\": \"2017-04-14T22:22:03.000Z\",\n        \"updated-at\": null\n      },\n      \"links\": {\n        \"self\": \"/topics/sports\"\n      }\n    }\n  ]\n}\n```\n\n### Pagination\n\n*Available since: `v0.1.4`*\n\nThe hook will also detect if `hook.result.skip`, `hook.result.limit` and `hook.result.total` are available as part of the `feathers-rest` provider. If available, it'll create `first`, `prev`, `next` and `last` links accordingly.\n\nThe raw pagination data is moved to a `meta` object.\n\n#### Example document with pagination links\n\n```json\n{\n  \"data\": [\n    {\n      \"type\": \"topics\",\n      \"id\": \"cinema\",\n      \"attributes\": {\n        \"name\": \"Cinema\",\n        \"show-role-title\": null,\n        \"created-at\": \"2017-04-14T22:22:03.000Z\",\n        \"updated-at\": null\n      },\n      \"links\": {\n        \"self\": \"/topics/cinema\"\n      }\n    },\n    {\n      \"type\": \"topics\",\n      \"id\": \"comedy\",\n      \"attributes\": {\n        \"name\": \"Comedy\",\n        \"show-role-title\": null,\n        \"created-at\": \"2017-04-14T22:22:03.000Z\",\n        \"updated-at\": null\n      },\n      \"links\": {\n        \"self\": \"/topics/comedy\"\n      }\n    }\n  ],\n  \"links\": {\n    \"next\": \"/topics?$skip=2\",\n    \"last\": \"/topics?$skip=14\"\n  },\n  \"meta\": {\n    \"total\": 15,\n    \"limit\": 2,\n    \"skip\": 0\n  }\n}\n```\n\n## Plain Object Serialization (POS) :new:\n\n*Available since: `v0.1.8`*\n\nCommon `Object` arrays can also be `jsonapified` for any custom service's `result`:\n\n### Multiple objects\n\n```js\n// Sample hook result, with multiple objects, from a `person` custom service.\nhook.result = [{\n  firstName: 'Joel',\n  lastName: 'Villarreal',\n  isEnabled: true\n}, {\n  firstName: 'Alejandro',\n  lastName: 'Bertoldi',\n  isEnabled: false\n}];\n```\n\n_JSONAPIfied_ result:\n\n```json\n{\n  \"data\": [\n    {\n      \"id\": \"2f1faeefc0edc081b012113e08cd9960773a70eb4d16626fade328adb9be4477\",\n      \"type\": \"person\",\n      \"attributes\": {\n        \"first-name\": \"Joel\",\n        \"last-name\": \"Villarreal\",\n        \"isEnabled\": true\n      },\n      \"links\": {\n        \"self\": \"/person/2f1faeefc0edc081b012113e08cd9960773a70eb4d16626fade328adb9be4477\"\n      }\n    },\n    {\n      \"id\": \"5ad0e862ce3db03640bb696d1ca77a0905ef4400070549622e577c4001f3e96d\",\n      \"type\": \"person\",\n      \"attributes\": {\n        \"first-name\": \"Alejandro\",\n        \"last-name\": \"Bertoldi\",\n        \"isEnabled\": false\n      },\n      \"links\": {\n        \"self\": \"/person/5ad0e862ce3db03640bb696d1ca77a0905ef4400070549622e577c4001f3e96d\"\n      }\n    }\n  ]\n}\n```\n\n### Single object\n\n```js\n// Sample hook result, with a single object in an array, from a `person` custom service.\nhook.result = [{\n  firstName: 'Joel',\n  lastName: 'Villarreal',\n  isEnabled: true\n}];\n\n// same as:\nhook.result = {\n  firstName: 'Joel',\n  lastName: 'Villarreal',\n  isEnabled: true\n};\n```\n\n_JSONAPIfied_ result:\n\n```json\n{\n  \"data\": {\n    \"id\": \"2f1faeefc0edc081b012113e08cd9960773a70eb4d16626fade328adb9be4477\",\n    \"type\": \"person\",\n    \"attributes\": {\n      \"first-name\": \"Joel\",\n      \"last-name\": \"Villarreal\",\n      \"isEnabled\": true\n    },\n    \"links\": {\n      \"self\": \"/person/2f1faeefc0edc081b012113e08cd9960773a70eb4d16626fade328adb9be4477\"\n    }\n  }\n}\n```\n\n### Identifier and type mapping\n\nThe `jsonapify` hook receives an `options` object that accepts two settings for POS:\n\n- `identifierKey`: the name of the property to convert into `id`\n- `typeKey`: the name of the property to convert into `type`\n\n#### What happens if I don't use `identifierKey`?\n\nThe hook's got your back. Using `crypto.createHash`, it creates a unique SHA-256 digest using the contents of the object.\n\n#### What happens if I don't use `typeKey`?\n\nThe hook will use the service's name (`hook.service.options.name`) as each model's type.\n\n## TODOs\n\nCheck out the [issues](https://github.com/joelalejandro/feathers-hooks-jsonapify/issues).\n\n## Feel like contributing?\n\nKnock yourself out! Fork the repo and make a PR.\n\n## Licence\n\nMIT\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoelalejandro%2Ffeathers-hooks-jsonapify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoelalejandro%2Ffeathers-hooks-jsonapify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoelalejandro%2Ffeathers-hooks-jsonapify/lists"}