From 3ddfe59e1529430246fdeacdb355922a513f23a9 Mon Sep 17 00:00:00 2001 From: Naz Date: Fri, 17 Feb 2023 16:57:57 +0800 Subject: [PATCH] Added resource caching to Posts/Pages Content API refs https://github.com/TryGhost/Toolbox/issues/522 - Browse endpoints for Posts and Pages are creating the most database traffic in the system. These are read-only endpoints that don't have to be fresh 100% of the time. Having optional cache allows to offload some of the database querying to more efficient storage. - To enable cache for Posts/Pages browse endpoints there are two prerequisites: - set 'hostSettings:postsPublicCache:enabled' to 'true' in the configuration file - add 'postsPublic' cache adapter in cache configuration - Example config for adapters with 60s TTL for a cached resource: ``` "adapters": { "cache": { "postsPublic": { "adapter": "Redis", "ttl": 60, "keyPrefix": "site_id_here:posts-content-api:" } } }, ``` --- ghost/core/core/boot.js | 2 ++ .../core/server/api/endpoints/pages-public.js | 4 ++- .../core/server/api/endpoints/posts-public.js | 4 ++- .../server/services/posts-public/index.js | 1 + .../server/services/posts-public/service.js | 31 +++++++++++++++++++ 5 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 ghost/core/core/server/services/posts-public/index.js create mode 100644 ghost/core/core/server/services/posts-public/service.js diff --git a/ghost/core/core/boot.js b/ghost/core/core/boot.js index 6d12e9d667..0458a24a6f 100644 --- a/ghost/core/core/boot.js +++ b/ghost/core/core/boot.js @@ -295,6 +295,7 @@ async function initServices({config}) { const emailAnalytics = require('./server/services/email-analytics'); const mentionsService = require('./server/services/mentions'); const tagsPublic = require('./server/services/tags-public'); + const postsPublic = require('./server/services/posts-public'); const urlUtils = require('./shared/url-utils'); @@ -313,6 +314,7 @@ async function initServices({config}) { members.init(), tiers.init(), tagsPublic.init(), + postsPublic.init(), membersEvents.init(), permissions.init(), xmlrpc.listen(), diff --git a/ghost/core/core/server/api/endpoints/pages-public.js b/ghost/core/core/server/api/endpoints/pages-public.js index 72e45c56e6..37adf11e50 100644 --- a/ghost/core/core/server/api/endpoints/pages-public.js +++ b/ghost/core/core/server/api/endpoints/pages-public.js @@ -1,6 +1,8 @@ const tpl = require('@tryghost/tpl'); const errors = require('@tryghost/errors'); const models = require('../../models'); +const postsPublicService = require('../../services/posts-public'); + const ALLOWED_INCLUDES = ['tags', 'authors', 'tiers']; const messages = { @@ -34,7 +36,7 @@ module.exports = { }, permissions: true, query(frame) { - return models.Post.findPage(frame.options); + return postsPublicService.api.browse(frame.options); } }, diff --git a/ghost/core/core/server/api/endpoints/posts-public.js b/ghost/core/core/server/api/endpoints/posts-public.js index 0da7e6aaaf..8e0e803d2a 100644 --- a/ghost/core/core/server/api/endpoints/posts-public.js +++ b/ghost/core/core/server/api/endpoints/posts-public.js @@ -1,6 +1,8 @@ const models = require('../../models'); const tpl = require('@tryghost/tpl'); const errors = require('@tryghost/errors'); +const postsPublicService = require('../../services/posts-public'); + const allowedIncludes = ['tags', 'authors', 'tiers', 'sentiment']; const messages = { @@ -34,7 +36,7 @@ module.exports = { }, permissions: true, query(frame) { - return models.Post.findPage(frame.options); + return postsPublicService.api.browse(frame.options); } }, diff --git a/ghost/core/core/server/services/posts-public/index.js b/ghost/core/core/server/services/posts-public/index.js new file mode 100644 index 0000000000..102ef66d4f --- /dev/null +++ b/ghost/core/core/server/services/posts-public/index.js @@ -0,0 +1 @@ +module.exports = require('./service'); diff --git a/ghost/core/core/server/services/posts-public/service.js b/ghost/core/core/server/services/posts-public/service.js new file mode 100644 index 0000000000..b8aa3c99a8 --- /dev/null +++ b/ghost/core/core/server/services/posts-public/service.js @@ -0,0 +1,31 @@ +class PostsPublicServiceWrapper { + async init() { + if (this.api) { + // Already done + return; + } + + // Wire up all the dependencies + const {Post} = require('../../models'); + const adapterManager = require('../adapter-manager'); + const config = require('../../../shared/config'); + + let postsCache; + if (config.get('hostSettings:postsPublicCache:enabled')) { + postsCache = adapterManager.getAdapter('cache:postsPublic'); + } + + const {PublicResourcesRepository} = require('@tryghost/public-resource-repository'); + + this.postsRepository = new PublicResourcesRepository({ + Model: Post, + cache: postsCache + }); + + this.api = { + browse: this.postsRepository.getAll.bind(this.postsRepository) + }; + } +} + +module.exports = new PostsPublicServiceWrapper();