1. 程式人生 > >Sail.js官方文件閱讀筆記(二)——api/controllers/ 目錄

Sail.js官方文件閱讀筆記(二)——api/controllers/ 目錄

Sails專案結構中api包包含了後端的主要邏輯。其中包含了多個主要目錄:

2.1 api/controllers/

此目錄中的js檔案包含了與models的互動邏輯與向客戶端渲染檢視。

2.1.1 總述

Actions是Sails應用中用來處理web請求的主要物件。

Actions和應用中的routes繫結,當用戶請求一個URL時,被繫結的action會執行邏輯和響應。

2.1.2 actions樣例

actions檔案有兩種形式:classic和actions2。

2.1.2.1 classic形式

傳統的方法新建一個action就是像函式一樣宣告。當客戶端請求一個繫結路徑的action時,此方法會形成一個請求物件作為第一個引數,形成一個響應物件作為第二個引數。如下是一個例子,通過id找使用者,或者展示歡迎介面,如果使用者找不到會轉到登入介面。

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});

}

2.1.2.2 actions2形式

與Sails helpers的工作方式類似,通過一種描述性定義來定義actions,它本質上是自文件化與自驗證性。例子如下:

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 (inputs, exits) {

      // 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: inputs.userId });

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

      // Display the welcome view.
      return exits.success({name: user.name});
   }
};

使用傳統的res,req方法可以減少程式碼量,但actions2有以下好處:

1. 程式碼不會直接依賴res和req,使其可以更好的複用和抽象入helpers。

2. 可以迅速決定action需要的請求引數的名字和型別,而且在action執行之前可以自動驗證。

3. 可以不用分析程式碼而看到執行action所有可能的結果。

在一個容器中,程式碼可以標準化,使之可以更容易複用和修改。因為可以首先宣告action的引數,可以更少可能暴露底部用例和安全漏洞。

2.1.2.3 退出標誌

在一個action,helper或指令碼中,預設丟擲任何東西都會引發錯誤返回。如果想要其他的返回,就必須丟擲一些特殊的標誌。比如:

return exits.hasConflictingCourses();

throw 'hasConflictingCourses';

throw { hasConflictingCourses: ['CS 301', 'M 402'] };

除了便於記憶,退出標誌在迴圈等結構中特別有用,但是仍想以一種特殊的方式退出。

2.1.3 controllers

編寫Sails應用最快的方法就是把各類操作都組織在controller檔案中。其檔名必須以Controller結尾,包含一組操作。例如:

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

2.1.4 獨立操作檔案

對於大型應用,使用獨立的操作檔案會更好。這種形式與所有操作都在一個controller檔案中相比,每個操作都在api/controller目錄下有獨立的檔案。例如:

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

每個js檔案都有一個包含req,res的方法或一個actions定義。

這種模式有幾種優勢:

1. 更容易追蹤應用中的動作,只要看檔案目錄即可,無須檢視程式碼。

2. 每個操作檔案都很小,比較容易維護,而controller檔案可能隨著應用複雜變大。

3. 針對操作檔案的路由更直觀。

4. 可以為高階操作設計目錄路由,可以用一個api/controller/index.js來繫結應用的 / 路由。

2.1.5 保持精簡

在MVC框架的傳統設計中,Sails應用的controller通常很簡單,因為可複用的程式碼都在helper中。這樣做可以在應用變得複雜時使程式碼更容易維護。但是,過早的把程式碼都移動到helper會引發一些維護問題,影響效率。

建議在使用到重複程式碼三次及以上時,將其移動到helper中進行復用。

2.2 api/models/

此目錄包含應用中的資料結構。

2.3 api/policies

此目錄中包含了js檔案本質上是express中介軟體為了對應用中controllers行為進行驗證。