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
@ -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)) {
let route;
let controller;
function routerChecker(value, endpoint, plugin) {
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.
if (!strapi.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);
// Parse each route from the user config, load policies if any
// 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 {
route = regex.detectRoute(endpoint);
const { route, policies, action } = routerChecker(value, endpoint);
// Check if the controller is a function.
if (typeof value.controller === 'function') {
action = value.controller;
} else {
controller = strapi.controllers[value.controller.toLowerCase()];
action = controller[value.action];
}
strapi.router[route.verb.toLowerCase()](route.endpoint, strapi.middlewares.compose(policies), action);
} catch (err) {
strapi.log.warn('Ignored attempt to bind route `' + endpoint + '` to unknown controller/action.');
}
});
// Init policies array.
policies = [];
// Parse each plugin's routes.
_.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`.
policies.push(globalPolicy(endpoint, value, route));
// Exclude routes with prefix.
const excludedRoutes = _.omitBy(value, o => !o.hasOwnProperty('prefix'));
// Add the `responsesPolicy`.
policies.push(responsesPolicy);
// Add others routes to the plugin's router.
_.forEach(_.omit(value, _.keys(excludedRoutes)), (value, endpoint) => {
const { route, policies, action } = routerChecker(value, endpoint, plugin);
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);
}
router[route.verb.toLowerCase()](route.endpoint, strapi.middlewares.compose(policies), action);
});
// /!\ Could override main router's routes.
if (!_.isEmpty(excludedRoutes)) {
_.forEach(excludedRoutes, (value, endpoint) => {
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) {
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.
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
// just remove it completely from the dictionary.