Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inject middleware instead of using router #75

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ jobs:

e2e_memory:
runs-on: ubuntu-latest
needs: [linters]

steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -81,7 +80,6 @@ jobs:

e2e_redis:
runs-on: ubuntu-latest
needs: [linters]

services:
redis:
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
"dev:memory": "yarn workspace @strapi-plugin-rest-cache/playground-memory develop",
"dev:redis": "yarn workspace @strapi-plugin-rest-cache/playground-redis develop",
"dev:couchbase": "yarn workspace @strapi-plugin-rest-cache/playground-couchbase develop",
"console:memory": "yarn workspace @strapi-plugin-rest-cache/playground-memory strapi console",
"console:redis": "yarn workspace @strapi-plugin-rest-cache/playground-redis strapi console",
"console:couchbase": "yarn workspace @strapi-plugin-rest-cache/playground-couchbase strapi console",
"profile:memory": "cd ./playgrounds/memory && 0x -o -D .profile -P 'autocannon --warmup [ -c 1 -d 3 ] -c 100 -p 10 -d 120 http://localhost:1337/api/homepage?populate=*' start-profiler.js",
"profile:redis": "cd ./playgrounds/redis && 0x -o -D .profile -P 'autocannon --warmup [ -c 1 -d 3 ] -c 100 -p 10 -d 120 http://localhost:1337/api/homepage?populate=*' start-profiler.js",
"profile:couchbase": "cd ./playgrounds/couchbase && 0x -o -D .profile -P 'autocannon --warmup [ -c 1 -d 3 ] -c 100 -p 10 -d 120 http://localhost:1337/api/homepage?populate=*' start-profiler.js",
Expand Down Expand Up @@ -71,4 +74,4 @@
"prettier --write"
]
}
}
}
41 changes: 5 additions & 36 deletions packages/strapi-plugin-rest-cache/server/bootstrap.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
'use strict';

/**
* @typedef {import('@strapi/strapi').Strapi} Strapi
*/
const chalk = require('chalk');
const debug = require('debug');

const { CacheProvider } = require('./types');
const { resolveUserStrategy } = require('./utils/config/resolveUserStrategy');
const { createRouter } = require('./utils/middlewares/createRouter');

const permissionsActions = require('./permissions-actions');

const { CacheProvider } = require('./types');
const createProvider = async (providerConfig, { strapi }) => {
const providerName = providerConfig.name.toLowerCase();
let provider;
Expand Down Expand Up @@ -53,22 +45,9 @@ const createProvider = async (providerConfig, { strapi }) => {
* @param {{ strapi: Strapi }} strapi
*/
async function bootstrap({ strapi }) {
// resolve user configuration, check for missing or invalid options
// resolve user configuration, check for missing or invalid optinos
const pluginOption = strapi.config.get('plugin.rest-cache');
const cacheStore = strapi.plugin('rest-cache').service('cacheStore');

if (pluginOption.strategy.debug === true) {
debug.enable('strapi:strapi-plugin-rest-cache');
}

const strategy = resolveUserStrategy(strapi, pluginOption.strategy);
strapi.config.set('plugin.rest-cache', {
...pluginOption,
strategy,
});

debug('strapi:strapi-plugin-rest-cache')('[STRATEGY]: %O', strategy);

// watch for changes in any roles -> clear all cache
// need to be done before lifecycles are registered
if (strapi.plugin('users-permissions')) {
Expand All @@ -79,30 +58,20 @@ async function bootstrap({ strapi }) {
},
});
}

// register cache provider
const provider = await createProvider(pluginOption.provider, { strapi });
strapi.plugin('rest-cache').service('cacheStore').init(provider);

// boostrap plugin permissions
await strapi.admin.services.permission.actionProvider.registerMany(
permissionsActions.actions
);

// boostrap cache middlewares
const router = createRouter(strapi, strategy);
strapi.server.router.use(router.routes());
// register cache provider
const provider = await createProvider(pluginOption.provider, { strapi });
cacheStore.init(provider);

strapi.log.info(
`Using REST Cache plugin with provider "${chalk.cyan(
pluginOption.provider.name
)}"`
);

if (strategy.resetOnStartup) {
strapi.log.warn('Reset cache on startup is enabled');
await strapi.plugin('rest-cache').service('cacheStore').reset();
}
}

module.exports = {
Expand Down
5 changes: 2 additions & 3 deletions packages/strapi-plugin-rest-cache/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ const { config } = require('./config');
const { controllers } = require('./controllers');
const { middlewares } = require('./middlewares');
const { routes } = require('./routes');
const { register } = require('./register')

module.exports = {
bootstrap,
destroy() {},
register,
config,
controllers,
routes,
services,
contentTypes: {},
policies: {},
middlewares,
};
42 changes: 42 additions & 0 deletions packages/strapi-plugin-rest-cache/server/register.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use strict';

/**
* @typedef {import('@strapi/strapi').Strapi} Strapi
*/
const debug = require('debug');

const { resolveUserStrategy } = require('./utils/config/resolveUserStrategy');
const { injectMiddlewares } = require('./utils/middlewares/injectMiddlewares');

/**
* @param {{ strapi: Strapi }} strapi
*/
async function register({ strapi }) {
// resolve user configuration, check for missing or invalid optinos
const pluginOption = strapi.config.get('plugin.rest-cache');
const cacheStore = strapi.plugin('rest-cache').service('cacheStore');

if (pluginOption.strategy.debug === true) {
debug.enable('strapi:strapi-plugin-rest-cache');
}

const strategy = resolveUserStrategy(strapi, pluginOption.strategy);
strapi.config.set('plugin.rest-cache', {
...pluginOption,
strategy,
});

debug('strapi:strapi-plugin-rest-cache')('[STRATEGY]: %O', strategy);

// boostrap cache middlewares
injectMiddlewares(strapi, strategy);

if (strategy.resetOnStartup) {
strapi.log.warn('Reset cache on startup is enabled');
await cacheStore.reset();
}
}

module.exports = {
register,
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
* @typedef {import('@strapi/strapi').Strapi} Strapi
*/

const debug = require('debug')('strapi:strapi-plugin-rest-cache');
const { getRelatedModelsUid } = require('./getRelatedModelsUid');
const { deepFreeze } = require('./deepFreeze');
const { routeExists } = require('./routeExists');
const {
CachePluginStrategy,
CacheRouteConfig,
Expand All @@ -17,6 +15,7 @@ const {
} = require('../../types');

const routeParamNameRegex = /:([^/]+)/g;
const routeParams = /(?<=\/\:).*?(?=\/|$)/g;

/**
* @param {Strapi} strapi
Expand All @@ -39,7 +38,9 @@ function resolveUserStrategy(strapi, userOptions) {
maxAge: userOptions.maxAge,
};

// Creating cache Config
for (const contentTypeOption of contentTypes) {
// string
if (typeof contentTypeOption === 'string') {
cacheConfigs.push({
...defaultModelConfig,
Expand All @@ -50,6 +51,7 @@ function resolveUserStrategy(strapi, userOptions) {
continue;
}

// Object
/**
* @type {CacheRouteConfig[]}
*/
Expand All @@ -71,6 +73,7 @@ function resolveUserStrategy(strapi, userOptions) {
})
);
} else {
// @TODO get the route of the value maby replace route with handler.
acc.push(
new CacheRouteConfig({
maxAge: defaultModelConfig.maxAge,
Expand Down Expand Up @@ -126,105 +129,64 @@ function resolveUserStrategy(strapi, userOptions) {
// get strapi api prefix
const apiPrefix = strapi.config.get('api.rest.prefix');

// https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/rest-api.html#api-endpoints
// https://github.com/strapi/strapi/blob/master/packages/core/strapi/lib/core-api/routes/index.js
if (cacheConfig.singleType) {
const base = `${apiPrefix}/${contentType.info.singularName}`;

// delete
cacheConfig.routes.push(
new CacheRouteConfig({
path: base,
method: 'DELETE',
keys: new CacheKeysConfig(cacheConfig.keys),
})
);
// update
cacheConfig.routes.push(
new CacheRouteConfig({
path: base,
method: 'PUT',
keys: new CacheKeysConfig(cacheConfig.keys),
})
);
// find
cacheConfig.routes.push(
new CacheRouteConfig({
path: base,
method: 'GET',
keys: new CacheKeysConfig(cacheConfig.keys),
maxAge: cacheConfig.maxAge,
hitpass: cacheConfig.hitpass,
})
);
} else {
const base = `${apiPrefix}/${contentType.info.pluralName}`;

// create
cacheConfig.routes.push(
new CacheRouteConfig({
path: base,
method: 'POST',
keys: new CacheKeysConfig(cacheConfig.keys),
})
);
// delete
cacheConfig.routes.push(
new CacheRouteConfig({
path: `${base}/:id`,
method: 'DELETE',
keys: new CacheKeysConfig(cacheConfig.keys),
paramNames: ['id'],
})
);
// update
cacheConfig.routes.push(
new CacheRouteConfig({
path: `${base}/:id`,
method: 'PUT',
keys: new CacheKeysConfig(cacheConfig.keys),
paramNames: ['id'],
})
);

// find
cacheConfig.routes.push(
new CacheRouteConfig({
path: base,
method: 'GET',
keys: new CacheKeysConfig(cacheConfig.keys),
maxAge: cacheConfig.maxAge,
hitpass: cacheConfig.hitpass,
})
);
// findOne
cacheConfig.routes.push(
new CacheRouteConfig({
path: `${base}/:id`,
method: 'GET',
paramNames: ['id'],
keys: new CacheKeysConfig(cacheConfig.keys),
maxAge: cacheConfig.maxAge,
hitpass: cacheConfig.hitpass,
})
);
}
}

for (const cacheConfig of cacheConfigs) {
cacheConfig.routes = cacheConfig.routes.filter((route) => {
const exist = routeExists(strapi, route);

if (!exist) {
debug(
'[WARNING] route "[%s] %s" not registered in strapi, ignoring...',
route.method,
route.path
);
for (const routes of Object.values(
strapi.api[contentType.info.singularName].routes
)) {
for (const route of routes.routes) {
// @TODO remove path and method and use the one
if (cacheConfig.singleType === true) {
const singleTypeMethod = ['GET', 'PUT', 'DELETE'];
if (
singleTypeMethod.includes(route.method) &&
route.path === `/${contentType.info.singularName}`
) {
cacheConfig.routes.push(
new CacheRouteConfig({
path: `/${apiPrefix}${route.path}`,
paramNames: route.path.match(routeParams) ?? [],
method: route.method,
keys: new CacheKeysConfig(cacheConfig.keys),
maxAge: cacheConfig.maxAge,
hitpass: cacheConfig.hitpass,
})
);
}
} else {
const CollectionTypeMethod = ['GET', 'POST'];
const CollectionTypeIdMethod = ['GET', 'PUT', 'DELETE'];
if (
CollectionTypeMethod.includes(route.method) &&
route.path === `/${contentType.info.pluralName}`
) {
cacheConfig.routes.push(
new CacheRouteConfig({
path: `/${apiPrefix}${route.path}`,
paramNames: route.path.match(routeParams) ?? [],
method: route.method,
keys: new CacheKeysConfig(cacheConfig.keys),
maxAge: cacheConfig.maxAge,
hitpass: cacheConfig.hitpass,
})
);
}
if (
CollectionTypeIdMethod.includes(route.method) &&
route.path === `/${contentType.info.pluralName}/:id`
) {
cacheConfig.routes.push(
new CacheRouteConfig({
path: `/${apiPrefix}${route.path}`,
paramNames: route.path.match(routeParams) ?? [],
method: route.method,
keys: new CacheKeysConfig(cacheConfig.keys),
maxAge: cacheConfig.maxAge,
hitpass: cacheConfig.hitpass,
})
);
}
}
}

return exist;
});
}
}

return deepFreeze(
Expand Down
Loading