1"use strict";(self.webpackChunkbackstage_microsite=self.webpackChunkbackstage_microsite||[]).push([["17336"],{11580(e,n,a){a.r(n),a.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var c=a(454634),s=a(474848),i=a(28453);let t={id:"cache",title:"Cache Service",sidebar_label:"Cache",description:"Documentation for the Cache service"},r,o={},l=[{value:"Configuration",id:"configuration",level:2},{value:"In-Memory (default)",id:"in-memory-default",level:3},{value:"Memcache",id:"memcache",level:3},{value:"Redis",id:"redis",level:3},{value:"Valkey",id:"valkey",level:3},{value:"Infinispan",id:"infinispan",level:3},{value:"Namespace Configuration",id:"namespace-configuration",level:3},{value:"Using the service",id:"using-the-service",level:2}];function d(e){let n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"This service lets your plugin interact with a cache. It is bound to your plugin too, so that you will only set and get values in your plugin's private namespace."}),"\n",(0,s.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,s.jsxs)(n.p,{children:["The cache service can be configured using the ",(0,s.jsx)(n.code,{children:"backend.cache"})," section in your ",(0,s.jsx)(n.code,{children:"app-config.yaml"}),":"]}),"\n",(0,s.jsx)(n.h3,{id:"in-memory-default",children:"In-Memory (default)"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"backend:\n cache:\n store: memory\n"})}),"\n",(0,s.jsx)(n.h3,{id:"memcache",children:"Memcache"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"backend:\n cache:\n store: memcache\n connection: user:[email protected]:11211\n"})}),"\n",(0,s.jsx)(n.h3,{id:"redis",children:"Redis"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"backend:\n cache:\n store: redis\n # Connection can be a simple URL string:\n connection: redis://localhost:6379\n # Or an object with additional options passed to the underlying client\n # (only supported for the Redis store):\n # connection:\n # url: redis://localhost:6379\n # pingInterval: 60000\n\n # Store-specific configuration (optional)\n redis:\n client:\n # Global namespace prefix for all cache keys\n namespace: 'my-app'\n # Separator used between namespace and plugin ID (default: ':')\n keyPrefixSeparator: ':'\n # Other Redis-specific options...\n clearBatchSize: 1000\n useUnlink: false\n"})}),"\n",(0,s.jsx)(n.h3,{id:"valkey",children:"Valkey"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"backend:\n cache:\n store: valkey\n connection: redis://localhost:6379\n\n # Store-specific configuration (optional)\n valkey:\n # Global namespace prefix for all cache keys (including separator used between namespace and plugin ID)\n keyPrefix: 'my-app:'\n"})}),"\n",(0,s.jsx)(n.h3,{id:"infinispan",children:"Infinispan"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"backend:\n cache:\n store: infinispan\n\n # Store-specific configuration (optional)\n infinispan:\n servers:\n # IP address or hostname of the server (default: '127.0.0.1')\n - host: 127.0.0.1\n # Port number of the server (default: '11222')\n port: 11222\n # Name of the cache (default: 'cache')\n cacheName: cache\n mediaType: application/json\n authentication:\n # Whether authentication is enabled (default: 'false')\n enabled: true\n userName: yourusername\n password: yourpassword\n saslMechanism: PLAIN\n"})}),"\n",(0,s.jsxs)(n.p,{children:["A full list of configuration items is available ",(0,s.jsx)(n.a,{href:"https://docs.jboss.org/infinispan/hotrod-clients/javascript/1.0/apidocs/module-infinispan.html",children:"here"}),", including support for backup clusters."]}),"\n",(0,s.jsx)(n.h3,{id:"namespace-configuration",children:"Namespace Configuration"}),"\n",(0,s.jsx)(n.p,{children:"For Redis and Valkey stores, you can configure a global namespace that will be prefixed to all cache keys:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Without namespace"}),": Cache keys use only the plugin ID (e.g., ",(0,s.jsx)(n.code,{children:"catalog:some-key"}),")"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"With namespace"}),": Cache keys use the format ",(0,s.jsx)(n.code,{children:"namespace:pluginId:key"})," (e.g., ",(0,s.jsx)(n.code,{children:"my-app:catalog:some-key"}),")"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For ",(0,s.jsx)(n.strong,{children:"Redis"}),", ",(0,s.jsx)(n.code,{children:"keyPrefixSeparator"})," controls what character is used between the namespace and plugin ID (defaults to ",(0,s.jsx)(n.code,{children:":"}),").\nFor ",(0,s.jsx)(n.strong,{children:"Valkey"}),", you set the full ",(0,s.jsx)(n.code,{children:"keyPrefix"})," including the separator."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": In-memory, Memcache and Infinispan stores do not support namespace configuration and will always use the plugin ID directly."]}),"\n",(0,s.jsx)(n.h2,{id:"using-the-service",children:"Using the service"}),"\n",(0,s.jsxs)(n.p,{children:["The following example shows how to get a cache client in your ",(0,s.jsx)(n.code,{children:"example"})," backend plugin and setting and getting values from the cache."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"import {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\n\ncreateBackendPlugin({\n pluginId: 'example',\n register(env) {\n env.registerInit({\n deps: {\n cache: coreServices.cache,\n },\n async init({ cache }) {\n const { key, value } = { key: 'test:key', value: 'bob' };\n await cache.set(key, value, { ttl: 1000 });\n\n // .. some other stuff.\n\n await cache.get(key); // 'bob'\n },\n });\n },\n});\n"})})]})}function h(e={}){let{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453(e,n,a){a.d(n,{R:()=>t,x:()=>r});var c=a(296540);let s={},i=c.createContext(s);function t(e){let n=c.useContext(i);return c.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),c.createElement(i.Provider,{value:n},e.children)}},454634(e){e.exports=JSON.parse('{"id":"backend-system/core-services/cache","title":"Cache Service","description":"Documentation for the Cache service","source":"@site/versioned_docs/version-stable/backend-system/core-services/cache.md","
1sourceDirName":"backend-system/core-services","slug":"/backend-system/core-services/cache","permalink":"/docs/backend-system/core-services/cache","draft":false,"unlisted":false,"editUrl":"https://github.com/backstage/backstage/edit/master/docs/backend-system/core-services/cache.md","tags":[],"version":"stable","frontMatter":{"id":"cache","title":"Cache Service","sidebar_label":"Cache","description":"Documentation for the Cache service"},"sidebar":"docs","previous":{"title":"Auth","permalink":"/docs/backend-system/core-services/auth"},"next":{"title":"Database","permalink":"/docs/backend-system/core-services/database"}}')}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.