{"id":15654350,"url":"https://github.com/simone-sanfratello/fastify-peekaboo","last_synced_at":"2025-04-30T23:48:54.785Z","repository":{"id":54246546,"uuid":"150217553","full_name":"simone-sanfratello/fastify-peekaboo","owner":"simone-sanfratello","description":"fastify plugin for memoizing responses by expressive settings","archived":false,"fork":false,"pushed_at":"2021-03-02T05:52:41.000Z","size":216,"stargazers_count":27,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-30T23:48:47.924Z","etag":null,"topics":["cache","fastify-plugin","memoize","nodejs"],"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/simone-sanfratello.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-09-25T06:26:26.000Z","updated_at":"2022-07-08T16:38:42.000Z","dependencies_parsed_at":"2022-08-13T10:00:17.128Z","dependency_job_id":null,"html_url":"https://github.com/simone-sanfratello/fastify-peekaboo","commit_stats":null,"previous_names":["braceslab/fastify-peekaboo"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simone-sanfratello%2Ffastify-peekaboo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simone-sanfratello%2Ffastify-peekaboo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simone-sanfratello%2Ffastify-peekaboo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simone-sanfratello%2Ffastify-peekaboo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simone-sanfratello","download_url":"https://codeload.github.com/simone-sanfratello/fastify-peekaboo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251801087,"owners_count":21645968,"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":["cache","fastify-plugin","memoize","nodejs"],"created_at":"2024-10-03T12:51:05.144Z","updated_at":"2025-04-30T23:48:54.761Z","avatar_url":"https://github.com/simone-sanfratello.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fastify-peekaboo\n\n[![NPM Version](http://img.shields.io/npm/v/fastify-peekaboo.svg?style=flat)](https://www.npmjs.org/package/fastify-peekaboo)\n[![NPM Downloads](https://img.shields.io/npm/dm/fastify-peekaboo.svg?style=flat)](https://www.npmjs.org/package/fastify-peekaboo)\n[![JS Standard Style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)\n![100% code coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)\n![Snyk Security Rate](https://snyk-widget.herokuapp.com/badge/npm/fastify-peekaboo/1.3.0/badge.svg)\n\nfastify plugin for memoize responses by expressive settings.\n\n## Purpose\n\nUse arbitrary cache to serve responses from previous elaboration, matching them by request and response.\n\n- [fastify-peekaboo](#fastify-peekaboo)\n  - [Purpose](#purpose)\n  - [Installing](#installing)\n    - [Quick start](#quick-start)\n  - [Storage and dataset](#storage-and-dataset)\n    - [Upgrade from v.1 to v.2](#upgrade-from-v1-to-v2)\n  - [Settings](#settings)\n    - [settings](#settings-1)\n      - [settings.rules](#settingsrules)\n      - [settings.mode](#settingsmode)\n      - [settings.storage](#settingsstorage)\n      - [settings.expire](#settingsexpire)\n      - [settings.xheader](#settingsxheader)\n      - [settings.noinfo](#settingsnoinfo)\n    - [Log](#log)\n  - [Documentation](#documentation)\n  - [Changelog](#changelog)\n  - [Roadmap](#roadmap)\n    - [v. 2.3](#v-23)\n    - [v. 2.4](#v-24)\n    - [v. 2.5](#v-25)\n  - [License](#license)\n\n## Installing\n\n````bash\nnpm i fastify-peekaboo\n````\n\n### Quick start\n\n```js\nconst fastify = require('fastify')\nconst peekaboo = require('fastify-peekaboo')\nconst fs = require('fs')\n\nconst _fastify = fastify()\n_fastify.register(peekaboo, {\n  // default settings: cache good stuff for 1 day\n  rules: [{\n    request: {\n      methods: true,\n      route: true\n    },\n    response: {\n      status: (code) =\u003e code \u003e 199 \u0026\u0026 code \u003c 300\n    }\n  }],\n  mode: 'memoize',\n  storage: { mode: 'memory' },\n  expire: 86400000, // 1 day in ms\n  xheader: true,\n  log: false\n})\n\n_fastify.get('/home', async (request, response) =\u003e {\n  const _home = 'welcome!'\n  response.send(_home)\n})\n\n_fastify.get('/image', async (request, response) =\u003e {\n  response.send(fs.createReadStream('image.png'))\n})\n\nawait _fastify.listen(80)\n```\n\nFirst call to `/home` or `/image` will execute the handler; from second time content will be served straight from the cache without running the handlers.\n\nCache storage can be `memory` (ram), `fs`.\n\n## Storage and dataset\n\n`dataset` feature allow to have different caches and switching between them.\n\nExample: create a new dataset and use it\n\n```js\nfastify.post('/dataset', async (request, response) =\u003e {\n  try {\n    const id = await _fastify.peekaboo.dataset.create(request.body.name)\n    await _fastify.peekaboo.dataset.set(id)\n    response.send({ id })\n  } catch (error) {\n    response.send({ message: error.message })\n  }\n})\n```\n\nSee [documentation](./doc/README.md#dataset) for full information and examples.\n\n### Upgrade from v.1 to v.2\n\nIf you are using `memory` storage, cache is volatile, no action is required.  \nIn order to keep cache using `fs` storage, move dir and content from `peekaboo` to `peekaboo/default`; otherwise, a new empty cache is created.\n\nUpdate API calls for `set.mode` and `get.mode` to `mode.set` and `mode.get`.\n\n## Settings\n\nCache works by matching request and response.  \nIf `request` (and `response`) match, `response` is saved by hashing the matching `request`.  \nThe first rule that match the request is choosen.\n\n### settings\n\n```js\n{\n  rules: MatchingRule[],\n  mode: Mode,\n  storage: Storage,\n  expire: number,\n  xheader: boolean,\n  noinfo: boolean\n}\n```\n\n#### settings.rules\n\nThe set of rules that indicate to use cache or not for requests.  \nSee [matching system](./doc/README.md#matching-system) for details.\n\n#### settings.mode\n\ntype: `string`, one of `memoize`, `off`, `collector`, `stock`\ndefault: `memoize`\n\nIt set how the cache system behave:\n\n- **memoize**  \n  on each request, if the relative cache entry is present serve that, or elaborate and cache on response if it doesn't\n- **collector**  \n  cache entries but don't use cache for serve responses\n- **stock**  \n  serve only responses from cache or `404` if the cache entry does not exists\n- **off**  \n  the plugin is not used at all\n\nYou can get/set also at runtime by\n\n```js\nfastify.get('/cache/mode', async (request, response) =\u003e {\n  response.send({ mode: fastify.peekaboo.mode.get() })\n})\nfastify.get('/cache/mode/:mode', async (request, response) =\u003e {\n  fastify.peekaboo.mode.set(request.params.mode)\n  response.send('set mode ' + request.params.mode)\n})\n```\n\n#### settings.storage\n\n- `mode`  \n  type: `string`  [ `memory` | `fs` ]  \n  default: `memory`  \n  - `memory` (default) cache use runtime memory\n  - `fs` use filesystem, need also `config.path`\n\n- storage `config`  \n  type: `object`  \n\n  for `file` mode\n  - `path`  \n    type: `string`  \n    dir path where files will be stored\n\n  ```js\n  {\n    mode: 'memory'\n  }\n\n  {\n    mode: 'fs',\n    config: { path: '/tmp/peekaboo' }\n  }\n  ```\n\nSee [storage documentation](./doc/README.md#storage) for further information about to access and manipulate entries.\n\n#### settings.expire\n\ntype: `number`  \ndefault: `86400000` // 1 day  \ncache expiration in ms, optional.\n\n#### settings.xheader\n\ntype: `boolean`  \ndefault: `true`  \nadd on response header `x-peekaboo` and `x-peekaboo-hash` if response comes from cache.\n\n#### settings.noinfo\n\ntype: `boolean`  \ndefault: `false`  \ndo not store info (matching rule, request) for entries, in order to speed up a little bit in write/read cache and save space; info are needed only for cache manipulation.\n\n### Log\n\nUse server log settings\n\n```js\nfastify({ logger: true })\n```\n\n## Documentation\n\nSee [documentation](./doc/README.md) for further information and examples.\n\n---\n\n## Changelog\n\n- **v. 2.3.1** [ 2021-03-02 ]\n  - fix route hashing\n\n- **v. 2.3.0** [ 2021-03-01 ]\n  - update deps\n\n- **v. 2.2.0** [ 2020-10-11 ]\n  - update matching `function` allow cache based on values, [see notes](./doc/README.md#match-by-function-notes)\n  - update documentation\n  - update deps\n\n- **v. 2.0.0** [ 2020-09-25 ]\n  - add `dataset` feature\n  - update `mode` public methods\n\n- **v. 1.3.0** [ 2020-07-25 ]\n  - stable version\n  - update to `fastify v3`\n  - update deps\n\n- **v. 1.2.0-beta** [ 2020-06-18 ] beta  \n  - move to `beta` stage\n  - fix fs storage persistence\n  - add `mode` (memoize, off, collector, stock)\n  - add storage access for editing: `get`, `list`, `set`, `rm`, `clear`\n  - add `info` in stored entries and `settings.noinfo` to skip that\n  - add `x-peekaboo-hash` in xheader\n\n- **v. 1.1.0-alpha** [ 2020-05-14 ] alpha  \n  - drop `keyv` storage\n\n- **v. 1.0.0-alpha** [ 2020-05-03 ] alpha  \n  - new matching system\n  - drop redis storage\n  - 100% test coverage\n  - validate settings with `superstruct`\n\n- **v. 0.5.0-beta** [ 2020-04-30 ] beta  \n  - upgrade dependencies\n\n- **v. 0.4.0-beta** [ 2019-05-21 ] beta  \n  - upgrade to `fastify v.2`\n  - fix redis connection close (by fork to keyv redis adapter https://github.com/simone-sanfratello/keyv-redis)\n\n- **v. 0.1.0-alpha** [ 2018-12-27 ] alpha  \n  - first release\n\n---\n\n## Roadmap\n\n### v. 2.3\n\n- [ ] remove `got` in favor of natvie `http` client\n- [ ] `response.rewrite` option\n- [ ] `request.rewrite` option\n- [ ] postgresql storage\n- [ ] redis storage\n\n### v. 2.4\n\n- [ ] doc: real world examples\n- [ ] benchmark plugin overhead (autocannon?)\n  - [ ] benchmark with different storages\n- [ ] support binary request/response (upload, download)\n- [ ] test edge cases\n  - [ ] querystring array or object\n- [ ] preset recipes (example graphql caching)\n- [ ] CI\n\n### v. 2.5\n\n- [ ] fine grained settings (storage, expiration, xheader ...) for each rule\n- [ ] invalidate cache (by ...?)\n- [ ] expire can be a function(request, response)\n\n---\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2018-2020 [Simone Sanfratello](https://braceslab.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimone-sanfratello%2Ffastify-peekaboo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimone-sanfratello%2Ffastify-peekaboo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimone-sanfratello%2Ffastify-peekaboo/lists"}