2017-01-10 5 views
0

간단한 GET 요청에 문제가있는 RESTful 처리를 위해 Blueprint API와 함께 돛을 사용하고 있습니다. 예를 들어 다음 모델을 생각해보십시오. 우리는 Project 전화 할게 :필터 조건에서 모델 속성으로 정의되지 않은 쿼리 매개 변수를 제외하는 방법

module.exports = { 

    attributes: { 
     id: { 
      type: 'string', 
      unique: true 
     }, 

     name: { 
      type: 'string' 
     }, 

     displayName: { 
      type: 'string' 
     }, 

     ... 
}; 

내가 정의 ProjectController.js이 청사진은 GET /project에서 나를 위해 경로를 설정합니다 가지고 있기 때문에. 이 URL에 요청하면이 모델에 대해 필터링되지 않은 결과가 모두 표시됩니다. limit, sortGET /project?limit=5과 같이 사용할 수있는 매개 변수도 있으며, 아직 내 결과가 5 개 이상 있다고 가정합니다.

limit과 같이 API 용으로 예약되지 않은 쿼리 매개 변수를 제공 할 때 문제가 발생합니다. 이제이 매개 변수를 필터 조건 (GET /project?foo)으로 사용하므로 결과가 없습니다.

내 모델은 sails.config.models.schema = true으로 설정되므로 attributes에 정의 된 필드 만 채워져 정크 정보는 저장되지 않습니다. 모델이 스키마를 따르도록 지정한 방법을 보면서, 속성으로 정의되지 않은 필터 조건도 무시하는 것이 이상적입니다. 기본적으로 GET /project?foofoo이 유효한 속성이 아니므로 모든 결과를 반환해야합니다.

주된 이유는 각 요청과 함께 캐시 버스터 매개 변수가 전송되므로 Sails가이를 필터 매개 변수로 해석하여 결과를 왜곡한다는 것입니다.

생각하십니까?

+0

일반 사항이거나 모델 지정 가능해야합니까? –

답변

0

MU의 후속 의견에 대한 응답으로, 여기에있는 아이디어는 모델 또는 컨트롤러와 관련이없는 일반적인 것입니다. 나는 정책을 사용하는 것에 대한 생각을 들여다 보았다. 그렇지만 각 정책에 대해 정책을 정의해야 할 필요가있다.이 정책은 경우에 따라 매개 변수의보다 구체적인 필터링을 허용하지 않는다.

최종 목표는 여기에 암시를 처리 청사진 이후 내 컨트롤러에있는 모든 방법을 정의 할 필요가없는 것이 었습니다 (예. GET project/ 자동 청사진 find() 방법을 사용합니다. 불행하게도, 난 완전히 정의하지 않아도 넘어갈 수 없습니다 내 난 아직 한 줄에 청사진 미들웨어를 호출 할 수 있기 때문에 자신의 ProjectController.find() 방법은, 그러나 꽤 합리적인 것 같다. 여기

요청 ( query, bodyparams)의 다른 범위에서 PARAMS을 제거하기위한 예시적인 유틸리티 모듈입니다. 희망적으로 스스로에 대한 발언 :

requestUtils.js

var _ = require('lodash'); 

module.exports = { 
    sanitizeRequestParams: function (req, scope, opts) { 
     var scopes = ['query', 'body', 'params'], 

      // global params to strip, keep and convert. Additional configurations can be supplied 
      // in the `opts` argument 
      stripParams = ['_dc'], 
      keepParams = [], 
      convertParams = { 

       /** 
       * Convert the `page` param into a calculated `skip` param for ORM 
       * 
       * The client-side framework will include the following for model 
       * requests: 
       *  ?_dc=XXX&limit=XX&page=XX&start=XX 
       * 
       * The only one ORM will not use for filter criteria is `limit`. So 
       * instead of using `page`, we will calculate the number of records 
       * to skip from the `page` and `limit` params and set that to the 
       * request instead. 
       * 
       * @param param The request param to be converted 
       * @param val The value of th =e request param 
       * @param req The Request object 
       * @returns {{skip: *}} 
       */ 
       'page': function (param, val, req) { 
        var limit = _.toInteger(req.query.limit); 

        if (!_.isInteger(limit)) { 
         limit = sails.config.blueprints.defaultLimit; 
        } 

        return {'skip': _.max([(_.toInteger(val) * limit) - limit, 0])}; 
       } 
      }; 

     // default to all if invalid scope specified 
     if (scopes.indexOf(scope) < 0) { 
      scope = 'all'; 
     } 

     opts = opts || {}; 

     // merge in user-provided configs with the defaults 
     stripParams = _.concat(stripParams, opts.strip || []); 
     keepParams = _.concat(keepParams, opts.keep || []); 
     convertParams = _.merge(convertParams, opts.convert || []); 

     // iterate over each of the scopes to process the params 
     _.forEach(scopes, function (currScope) { 
      if (scope === currScope || scope === 'all') { 

       // strip the defined params from the request, optionally 
       // keeping the ones marked as such 
       _.forEach(stripParams, function (param) { 
        if (keepParams.indexOf(param) < 0) { 

         // eg: deletes `request.query._dc` 
         delete req[currScope][param]; 
        } 
       }); 

       // iterate the params to be converted to a new param 
       _.forEach(convertParams, function (fn, param) { 
        var newParam; 

        // ensure the orig param exists before writing a new one 
        if (req[currScope][param]) { 
         newParam = fn(param, req[currScope][param], req); 

         // eg: deletes `request.query.page` 
         // adds `request.query.skip` with a calculated value 
         delete req[currScope][param]; 
         _.merge(req[currScope], newParam); 
        } 
       }); 
      } 
     }); 
    } 
}; 

ProjectController.js

module.exports = { 

    find: function (req, res) { 
     // before: ?_dc=XXXXX&page=XX&limit=XX&start=XX 
     // after: ?limit=XX&skip=XX 
     util.sanitizeRequestParams(req, 'query', {strip: ['start']}); 

     // let Blueprints handle the `find` method like we never existed 
     return sails.hooks.blueprints.middleware.find(req, res); 
    } 
}; 

는 라이프 사이클 콜백 또는 후크로이 같은를 처리하기 훨씬 청소기 방법이있을 수 있습니다. 나는 지금까지 돛이나 노드를 사용하지 않았으므로 여전히 나에게 녹색이다. 모든 의견을 보내 주시면 감사하겠습니다.