Create a sub-router for each plugin, but allows plugins to override main's routes

This commit is contained in:
Aurélien Georget 2016-09-01 18:32:04 +02:00
parent 4a552298e0
commit c4c58f3c9a
2 changed files with 75 additions and 31 deletions

View File

@ -1,4 +1,4 @@
'use strict'; 'use strict';
/** /**
* Module dependencies * Module dependencies
@ -53,12 +53,46 @@ module.exports = strapi => {
}; };
} }
if (((cluster.isWorker && strapi.config.reload.workers > 0) || (cluster.isMaster && strapi.config.reload.workers < 1)) || (!strapi.config.reload && cluster.isMaster)) { function routerChecker(value, endpoint, plugin) {
let route;
let controller;
let action; let action;
let policies = []; const route = regex.detectRoute(endpoint);
// Check if the controller is a function.
if (typeof value.controller === 'function') {
action = value.controller;
} else {
const controller = strapi.controllers[value.controller.toLowerCase()] || strapi.plugins[plugin].controllers[value.controller.toLowerCase()];
action = controller[value.action];
}
// Init policies array.
const policies = [];
// Add the `globalPolicy`.
policies.push(globalPolicy(endpoint, value, route));
// Add the `responsesPolicy`.
policies.push(responsesPolicy);
if (_.isArray(value.policies) && !_.isEmpty(value.policies)) {
_.forEach(value.policies, policy => {
if (strapi.policies[policy]) {
policies.push(strapi.policies[policy]);
} else {
strapi.log.error('Ignored attempt to bind route `' + endpoint + '` with unknown policy `' + policy + '`.');
process.exit(1);
}
});
}
return {
route: route,
policies: policies,
action: action
};
}
if (((cluster.isWorker && strapi.config.reload.workers > 0) || (cluster.isMaster && strapi.config.reload.workers < 1)) || (!strapi.config.reload && cluster.isMaster)) {
// Initialize the router. // Initialize the router.
if (!strapi.router) { if (!strapi.router) {
strapi.router = strapi.middlewares.router({ strapi.router = strapi.middlewares.router({
@ -66,43 +100,50 @@ module.exports = strapi => {
}); });
} }
// Add response policy to the global variable // Add response policy to the global variable.
_.set(strapi.policies, 'responsesPolicy', responsesPolicy); _.set(strapi.policies, 'responsesPolicy', responsesPolicy);
// Parse each route from the user config, load policies if any // Parse each route from the user config, load policies if any
// and match the controller and action to the desired endpoint. // and match the controller and action to the desired endpoint.
_.forEach(strapi.config.routes, (value, endpoint) => { _.forEach(_.omit(strapi.config.routes, 'plugins'), (value, endpoint) => {
try { try {
route = regex.detectRoute(endpoint); const { route, policies, action } = routerChecker(value, endpoint);
// Check if the controller is a function. strapi.router[route.verb.toLowerCase()](route.endpoint, strapi.middlewares.compose(policies), action);
if (typeof value.controller === 'function') { } catch (err) {
action = value.controller; strapi.log.warn('Ignored attempt to bind route `' + endpoint + '` to unknown controller/action.');
} else { }
controller = strapi.controllers[value.controller.toLowerCase()]; });
action = controller[value.action];
}
// Init policies array. // Parse each plugin's routes.
policies = []; _.forEach(strapi.config.routes.plugins, (value, plugin) => {
try {
// Create router for each plugin.
// Prefix router with the plugin's name.
const router = strapi.middlewares.router({
prefix: plugin
});
// Add the `globalPolicy`. // Exclude routes with prefix.
policies.push(globalPolicy(endpoint, value, route)); const excludedRoutes = _.omitBy(value, o => !o.hasOwnProperty('prefix'));
// Add the `responsesPolicy`. // Add others routes to the plugin's router.
policies.push(responsesPolicy); _.forEach(_.omit(value, _.keys(excludedRoutes)), (value, endpoint) => {
const { route, policies, action } = routerChecker(value, endpoint, plugin);
if (_.isArray(value.policies) && !_.isEmpty(value.policies)) { router[route.verb.toLowerCase()](route.endpoint, strapi.middlewares.compose(policies), action);
_.forEach(value.policies, policy => { });
if (strapi.policies[policy]) {
policies.push(strapi.policies[policy]); // /!\ Could override main router's routes.
} else { if (!_.isEmpty(excludedRoutes)) {
strapi.log.error('Ignored attempt to bind route `' + endpoint + '` with unknown policy `' + policy + '`.'); _.forEach(excludedRoutes, (value, endpoint) => {
process.exit(1); const { route, policies, action } = routerChecker(value, endpoint, plugin);
}
strapi.router[route.verb.toLowerCase()](route.endpoint, strapi.middlewares.compose(policies), action);
}); });
} }
strapi.router[route.verb.toLowerCase()](route.endpoint, strapi.middlewares.compose(policies), action);
strapi.router.use(router.routes(), router.allowedMethods());
} catch (err) { } catch (err) {
strapi.log.warn('Ignored attempt to bind route `' + endpoint + '` to unknown controller/action.'); strapi.log.warn('Ignored attempt to bind route `' + endpoint + '` to unknown controller/action.');
} }

View File

@ -133,7 +133,10 @@ module.exports = strapi => {
}; };
// Delete the definition if it's empty. // Delete the definition if it's empty.
strapi.plugins[plugin.name] = _.omitBy(strapi.plugins[plugin.name], _.isEmpty); strapi.plugins[plugin.name] = _.omitBy(_.get(strapi.plugins, plugin.name), _.isEmpty);
// Merge API routes with the main ones.
_.set(strapi.config.routes, 'plugins.' + plugin.name, _.get(strapi.plugins, plugin.name + '.config.routes'));
// If the module doesn't have a definition at all // If the module doesn't have a definition at all
// just remove it completely from the dictionary. // just remove it completely from the dictionary.