天天看点

Sail.js官方文档阅读笔记(五)——Actions and controllers总述定义在何处Actions示例Controllers独立actions保持“瘦”

总述

Actions是Sails项目中对客户端响应请求的部分,它是model和view的中间层,负责梳理业务逻辑。

Actions是项目中的路由,当客户端请求一个URL时,将经由它执行逻辑并响应。

定义在何处

Actions通常定义在api/controllers目录下。

Actions示例

Actions文件通常有两种组织形式,actions2(推荐)和传统的。

Actions2:

module.exports = {

   friendlyName: 'Welcome user',

   description: 'Look up the specified user and welcome them, or redirect to a signup page if no user was found.',

   inputs: {
      userId: {
        description: 'The ID of the user to look up.',
        // By declaring a numeric example, Sails will automatically respond with `res.badRequest`
        // if the `userId` parameter is not a number.
        type: 'number',
        // By making the `userId` parameter required, Sails will automatically respond with
        // `res.badRequest` if it's left out.
        required: true
      }
   },

   exits: {
      success: {
        responseType: 'view',
        viewTemplatePath: 'pages/welcome'
      },
      notFound: {
        description: 'No user with the specified ID was found in the database.',
        responseType: 'notFound'
      }
   },

   fn: async function ({userId}) {

      // Look up the user whose ID was specified in the request.
      // Note that we don't have to validate that `userId` is a number;
      // the machine runner does this for us and returns `badRequest`
      // if validation fails.
      var user = await User.findOne({ id: userId });

      // If no user was found, respond "notFound" (like calling `res.notFound()`)
      if (!user) { throw 'notFound'; }

      // Display a personalized welcome view.
      return {
        name: user.name
      };
   }
};
           

使用传统的(req, res)方法来写actions会减少代码量,但使用actions2有如下好处:

  • 代码不必依赖于req和res,使其更容易抽象成helper
  • 可以及早确定actions需要的请求参数名和类型,在action运行时可以自动验证
  • 不必仔细分析代码就能知道action所有可能的输出结果

传统:

module.exports = async function welcomeUser (req, res) {

  // Get the `userId` parameter from the request.
  // This could have been set on the querystring, in
  // the request body, or as part of the URL used to
  // make the request.
  var userId = req.param('userId');

   // If no `userId` was specified, or it wasn't a number, return an error.
  if (!_.isNumeric(userId)) {
    return res.badRequest(new Error('No user ID specified!'));
  }

  // Look up the user whose ID was specified in the request.
  var user = await User.findOne({ id: userId });

  // If no user was found, redirect to signup.
  if (!user) {
    return res.redirect('/signup' );
  }

  // Display the welcome view, setting the view variable
  // named "name" to the value of the user's name.
  return res.view('welcome', {name: user.name});

}
           

Controllers

生成Sails最快的方式就是把actions组织到controllers文件中。例如:

module.exports = {
  login: function (req, res) { ... },
  logout: function (req, res) { ... },
  signup: function (req, res) { ... },
};
           

独立actions

对于大型成熟的系统,独立的actions可能是比controllers更好的方式。并非多个actions写在一个文件中,而是每个action都有一个独立的文件在api/controller目录下。如:

api/
 controllers/
  user/
   login.js
   logout.js
   signup.js
           

保持“瘦”

和多数MVC框架一样,controller都是很瘦的一层。因为可重用的代码通常会被移到helpers或者提取到modules中。这使得项目变复杂的过程中更容易维护。

有一个规则:当使用同样代码的地方达到3处,即可将其移入helper中。