问题描述:

I am starting to write a hook to override the json format returned by res.ok(). What is the best way to go about this? I would like to avoid changing the files in api/responses and instead override them, if possible.

The hooks README hasn't been updated in two years, but it mentions:

  • Custom API responses (coming in v0.10: Stage 2 - Unstable)

Is that now possible? It looks like the default hook uses hook.middleware = responseDefs;, is that a viable option for an installable hook?

网友答案:

I'm not entirely happy with my solution, but I was able to rip out a few helper functions from core which bind my response to the route after all the other hooks have loaded.

In particular, I copied and tweaked loadResponses and bindToSails from moduleloader:


let buildDictionary = require('sails-build-dictionary');
let path = require('path');
let _ = require('lodash');

function bindToSails(sails, cb) {
  return function (err, modules) {
    if (err) {
      return cb(err);
    }
    _.each(modules, function (module) {
      // Add a reference to the Sails app that loaded the module
      module.sails = sails;
      // Bind all methods to the module context
      _.bindAll(module);
    });
    return cb(null, modules);
  };
}


/**
 * Load custom API responses.
 *
 * @param {Object} options
 * @param {Function} cb
 */
exports.loadResponses = function (sails, cb) {
  buildDictionary.optional({
    dirname              : path.resolve(__dirname + '/../responses'),
    filter               : /(.+)\.js$/,
    useGlobalIdForKeyName: true
  }, bindToSails(sails, cb));
};

Then, from within my hook definition, I put:

loadModules: function (cb) {
  let hook = this;
  moduleUtils.loadResponses(sails, function (err, responseDefs) {
    if (err) return cb(err);
    // Register responses as middleware
    hook.middleware.responses = responseDefs;
    return cb();
  });
},

/**
 * Shadow route bindings
 * @type {Object}
 */
routes: {
  before: {

    /**
     * Add custom response methods to `res`.
     *
     * @param {Request} req
     * @param {Response} res
     * @param  {Function} next [description]
     * @api private
     */
    'all /*': function addResponseMethods(req, res, next) {
      // Attach custom responses to `res` object
      // Provide access to `req` and `res` in each of their `this` contexts.
      _.each(sails.middleware.jsonapi.responses, function eachMethod(responseFn, name) {
        sails.log.silly('Binding response ' + name + ' to ' + responseFn);
        res[name] = _.bind(responseFn, {
          req: req,
          res: res,
        });
      });
      // Proceed!
      next();
    }
  }
}

Where jsonapi is the name of my hook. You can see the whole thing in action at: https://github.com/IanVS/sails-hook-jsonapi/

相关阅读:
Top