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:"
            }
        }
    },
```
This commit is contained in:
Naz 2023-02-17 16:57:57 +08:00
parent c3d7104367
commit 3ddfe59e15
No known key found for this signature in database
5 changed files with 40 additions and 2 deletions

View File

@ -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(),

View File

@ -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);
}
},

View File

@ -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);
}
},

View File

@ -0,0 +1 @@
module.exports = require('./service');

View File

@ -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();