Skip to content

Instantly share code, notes, and snippets.

@x-yuri
Last active October 15, 2019 18:23
Show Gist options
  • Save x-yuri/1dc385a4afb333018c325a0a556c910b to your computer and use it in GitHub Desktop.
Save x-yuri/1dc385a4afb333018c325a0a556c910b to your computer and use it in GitHub Desktop.
strapi: prefix the endpoints

config/environments/production/custom.json:

{
  "prefixed-router": {
    "enabled": true
  }
}

config/middleware.json:

...
    "after": [
      ..., "router", "prefixed-router"
    ],
...

middlewares/prefixed-router/index.js

'use strict';

// --- admin/node_modules/strapi/lib/middlewares/router/index.js
// +++ admin/middlewares/prefixed-router/index.js
// @@ -13,7 +13,7 @@
//   */
//  
//  module.exports = strapi => {
// -  const composeEndpoint = require('./utils/composeEndpoint')(strapi);
// +  const composeEndpoint = require('strapi/lib/middlewares/router/utils/composeEndpoint')(strapi);
//  
//    return {
//      /**
// @@ -22,13 +22,15 @@
//  
//      initialize() {
//        _.forEach(strapi.config.routes, value => {
// -        composeEndpoint(value, null, strapi.router);
// +        const prefixedValue = Object.assign({}, value, {path: '/api' + value.path});
// +        composeEndpoint(prefixedValue, null, strapi.router);
//        });
//  
//        strapi.router.prefix(
//          _.get(strapi.config, 'currentEnvironment.request.router.prefix', '')
//        );
//  
// +/*
//        if (!_.isEmpty(_.get(strapi.admin, 'config.routes', false))) {
//          // Create router for admin.
//          // Prefix router with the admin's name.
// @@ -47,6 +49,7 @@
//          // Mount admin router on Strapi router
//          strapi.app.use(router.middleware());
//        }
// +*/
//  
//        if (strapi.plugins) {
//          // Parse each plugin's routes.
// @@ -66,12 +69,13 @@
//              }
//            );
//  
// -          router.prefix(`/${name}`);
// +          router.prefix(`/api/${name}`);
//  
//            // /!\ Could override main router's routes.
//            if (!_.isEmpty(excludedRoutes)) {
//              _.forEach(excludedRoutes, value => {
// -              composeEndpoint(value, name, strapi.router);
// +              const prefixedValue = Object.assign({}, value, {path: '/api' + value.path});
// +              composeEndpoint(prefixedValue, name, strapi.router);
//              });
//            }

/**
 * Module dependencies
 */

// Public node modules.
const _ = require('lodash');
const routerJoi = require('koa-joi-router');

/**
 * Router hook
 */

module.exports = strapi => {
  const composeEndpoint = require('strapi/lib/middlewares/router/utils/composeEndpoint')(strapi);

  return {
    /**
     * Initialize the hook
     */

    initialize() {
      _.forEach(strapi.config.routes, value => {
        const prefixedValue = Object.assign({}, value, {path: '/api' + value.path});
        composeEndpoint(prefixedValue, null, strapi.router);
      });

      strapi.router.prefix(
        _.get(strapi.config, 'currentEnvironment.request.router.prefix', '')
      );

/*
      if (!_.isEmpty(_.get(strapi.admin, 'config.routes', false))) {
        // Create router for admin.
        // Prefix router with the admin's name.
        const router = routerJoi();

        _.forEach(strapi.admin.config.routes, value => {
          composeEndpoint(value, null, router);
        });

        // router.prefix(strapi.config.admin.path || `/${strapi.config.paths.admin}`);
        router.prefix('/admin');

        // TODO:
        // - Mount on main router `strapi.router.use(routerAdmin.middleware());`

        // Mount admin router on Strapi router
        strapi.app.use(router.middleware());
      }
*/

      if (strapi.plugins) {
        // Parse each plugin's routes.
        _.forEach(strapi.plugins, (plugin, name) => {
          const router = routerJoi();

          // Exclude routes with prefix.
          const excludedRoutes = _.omitBy(
            plugin.config.routes,
            o => !o.config.hasOwnProperty('prefix')
          );

          _.forEach(
            _.omit(plugin.config.routes, _.keys(excludedRoutes)),
            value => {
              composeEndpoint(value, name, router);
            }
          );

          router.prefix(`/api/${name}`);

          // /!\ Could override main router's routes.
          if (!_.isEmpty(excludedRoutes)) {
            _.forEach(excludedRoutes, value => {
              const prefixedValue = Object.assign({}, value, {path: '/api' + value.path});
              composeEndpoint(prefixedValue, name, strapi.router);
            });
          }

          // TODO:
          // - Mount on main router `strapi.router.use(router.middleware());`

          // Mount plugin router
          strapi.app.use(router.middleware());
        });
      }

      // Let the router use our routes and allowed methods.
      strapi.app.use(strapi.router.middleware());
    },
  };
};

There are 3 types of routes router middleware adds: user, admin, and plugin endpoints. Above I prefix user and plugin endpoints. But plugins generally need somestatic files when working as part of the admin site. Those are served by public middleware, and are not prefixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment