foomo-docs/assets/js/020a1d6e.70516b8a.js
2023-02-27 14:32:32 +00:00

1 line
11 KiB
JavaScript

"use strict";(self.webpackChunkfoomo=self.webpackChunkfoomo||[]).push([[3174],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,a,o=function(e,t){if(null==e)return{};var n,a,o={},r=Object.keys(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var i=a.createContext({}),l=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=l(e.components);return a.createElement(i.Provider,{value:t},e.children)},h="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,i=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),h=l(n),d=o,f=h["".concat(i,".").concat(d)]||h[d]||p[d]||r;return n?a.createElement(f,c(c({ref:t},u),{},{components:n})):a.createElement(f,c({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,c=new Array(r);c[0]=d;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[h]="string"==typeof e?e:o,c[1]=s;for(var l=2;l<r;l++)c[l]=n[l];return a.createElement.apply(null,c)}return a.createElement.apply(null,n)}d.displayName="MDXCreateElement"},6806:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var a=n(7462),o=(n(7294),n(3905));const r={},c="Caching",s={unversionedId:"projects/cms/gocontentful/caching",id:"projects/cms/gocontentful/caching",title:"Caching",description:"Caching is a fundamental part of working with remote data across the Internet,",source:"@site/docs/projects/cms/gocontentful/05-caching.md",sourceDirName:"projects/cms/gocontentful",slug:"/projects/cms/gocontentful/caching",permalink:"/docs/projects/cms/gocontentful/caching",draft:!1,editUrl:"https://github.com/foomo/foomo-docs/tree/main/foomo/docs/projects/cms/gocontentful/05-caching.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{},sidebar:"projectsSidebar",previous:{title:"Working with the Gocontentful API",permalink:"/docs/projects/cms/gocontentful/working-with-gocontentful-api"},next:{title:"API Reference",permalink:"/docs/projects/cms/gocontentful/api-reference"}},i={},l=[{value:"Full cache init and rebuild",id:"full-cache-init-and-rebuild",level:4},{value:"Sync API support",id:"sync-api-support",level:4},{value:"Cache timeout",id:"cache-timeout",level:3},{value:"Asset caching",id:"asset-caching",level:3},{value:"When to use and not use caching",id:"when-to-use-and-not-use-caching",level:3}],u={toc:l},h="wrapper";function p(e){let{components:t,...n}=e;return(0,o.kt)(h,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"caching"},"Caching"),(0,o.kt)("p",null,"Caching is a fundamental part of working with remote data across the Internet,\nwhere access is severely impacted by latency and transfer time. In real-world scenarios,\nyou'll always need to keep all the data you need close and sync the changes with the remote\nCMS when they happen. "),(0,o.kt)("p",null,"Gocontentful supports caching out of the box. The client can maintain a cache of an entire space\nor a subset of the content types that can be initialized with a single method call:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'contentTypes := []string{"person", "pet"}\nerr = cc.UpdateCache(context, contentTypes, true)\n')),(0,o.kt)("p",null,"This makes sense for client modes ",(0,o.kt)("inlineCode",{parentName:"p"},"ClientModeCDA")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"ClientModeCPA")," and not for the management API.\nThe client will download all the entries, convert and store them in the case as\nnative Go value objects. This makes subsequent accesses to the space data an in-memory operation removing all the HTTP\noverhead."),(0,o.kt)("p",null,"The first parameter is the context. If you don't use a context in your application or service just pass ",(0,o.kt)("em",{parentName:"p"},"context.Background()")),(0,o.kt)("p",null,"The third parameter of UpdateCache toggles asset caching on or off. If you deal with assets you want this to be always on."),(0,o.kt)("h4",{id:"full-cache-init-and-rebuild"},"Full cache init and rebuild"),(0,o.kt)("p",null,"By default the client will cache the whole space using 4 parallel workers to speed up the process.\nThis is safe since Contentful allows up to 5 concurrent connections.\nIf you have content types that have a lot of entries, it might make sense to keep them close to each other\nin the content types slice passed to UpdateCache(), so that they will run in parallel and not one after the other."),(0,o.kt)("p",null,"All gocontentful functions that query the space cache-transparent: if a cache is available data will be loaded from\nthere, otherwise it will be sourced from Contentful. This doesn't apply to ",(0,o.kt)("em",{parentName:"p"},"GetFilteredXYZ()")," calls that\nalways need to pass the query to Contentful. "),(0,o.kt)("p",null,"Gocontentful also supports selective entry and asset cache updates through the following method:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"err = cc.UpdateCacheForEntity(context, sysType, contentType, entityID string)\n")),(0,o.kt)("p",null,"When something changes in the space at Contentful you need to update the cache. For this to happen you need to set\nup a webhook at Contentful and handle its calls in your service through a public HTTP listener.\nWhen a webhook call gets in, you have the choice of updating your cache in different ways:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"You can regenerate the entire CDA cache when something is published because you want production data to\nbe 100% up to date in your application. This can get slow and expensive."),(0,o.kt)("li",{parentName:"ul"},"You can alternatively update a single entry in the cache. This is usually the case for the CPA cache because\nit's a lot faster and that works well for preview features."),(0,o.kt)("li",{parentName:"ul"},"You can use the Sync API, but only limited to ",(0,o.kt)("inlineCode",{parentName:"li"},"ClientModeCDA"),", as explained in the following paragraph.")),(0,o.kt)("p",null,"In any case, if an update fails the previous cache is preserved to prevent service disruption.\nIn the unfortunate case a service or application needs to start and Contentful is not available, Gocontentful can work\nin an offline mode if you call ",(0,o.kt)("em",{parentName:"p"},"SetOfflineFallback")," on the client after you create it passing the path to a space export file."),(0,o.kt)("p",null,"The gocontentful API can work entirely offline too. In this case a cache is created from a space export file and most of the\nfeatures are available (pretty obviously, those that don't require live access to the space, like custom queries). If you update\nthe export file periodically you can even update the cache from the updated file."),(0,o.kt)("h4",{id:"sync-api-support"},"Sync API support"),(0,o.kt)("p",null,"In versions v1.0.12 and newer, gocontentful supports the Contentful Sync API and that's now the recommended way to cache spaces and manage updates.\nSync is enabled by default when you create a client with CDA mode.\nTo enable or disable support for the Sync API explicitly, you can call the SetSyncMode method on the client:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"cc.SetSyncMode(true)\n")),(0,o.kt)("p",null,"With sync on, the cache updates will happen transparently through downloads of incremental changes.\nThe syntax to update the cache doesn't change, just call ",(0,o.kt)("em",{parentName:"p"},"UpdateCache")," on the client as usual."),(0,o.kt)("p",null,"The initialization of the cache will be slower when ",(0,o.kt)("em",{parentName:"p"},"SyncMode")," is on compared to the legacy full cache init because sync calls cannot be parallelized.\nSubsequent updates though will be much faster because only changes in the space from the previous sync will be downloaded.\nThis includes entries and assets that were deleted. In case of need you can call ",(0,o.kt)("em",{parentName:"p"},"ResetSync()")," to start over from a fresh empty cache."),(0,o.kt)("p",null,"Note that the Sync API is not officially supported by Contentful on the Preview API. At the time of this writing it seems to work but use it at your own risk."),(0,o.kt)("h3",{id:"cache-timeout"},"Cache timeout"),(0,o.kt)("p",null,"Cache update operations time out by default after 120 seconds. This makes sure that no\nroutine is left hanging, blocking subsequent updates in case the main application or service\nrecovers from a panic. If you need to increase this limit because you have a huge space with\na lot of entries you can use the ",(0,o.kt)("em",{parentName:"p"},"SetCacheUpdateTimeout")," method. See the ",(0,o.kt)("a",{parentName:"p",href:"./api-reference"},"API Reference")," for details."),(0,o.kt)("h3",{id:"asset-caching"},"Asset caching"),(0,o.kt)("p",null,"If you use assets in your space, then you absolutely need to enable them in the ",(0,o.kt)("em",{parentName:"p"},"UpdateCache")," call.\nOtherwise, every time an entry needs to resolve a reference to an asset that single asset will be downloaded\nand that for large spaces with thousands of assets can lead to incredibly slow operation."),(0,o.kt)("h3",{id:"when-to-use-and-not-use-caching"},"When to use and not use caching"),(0,o.kt)("p",null,"Simple answer is: you should almost always use caching. The only scenario where not using\na cache on the client is better is when you only need to download a very limited amount\nof entries (in the order of less than some hundreds) and do that at significant distance in time\n(e.g. every hour). In this case your application code can be simpler and there won't be any\nperformance penalty. The other case is when you need to run a lot of custom queries or\nuse XPath, which is currently not supported by gocontentful directly."))}p.isMDXComponent=!0}}]);