Sails.js默认REST接口关联字段过滤方法咨询
当然可以!在Sails.js里,你有好几种灵活的方式来控制默认REST接口返回的内容,避免关联嵌套带来的问题。下面给你梳理几个常用的方案:
方法一:重写模型的
toJSON()方法 这是最常用的方案之一,因为Sails在返回JSON响应前,会自动调用模型的toJSON()方法处理数据。你可以在这里精准控制要保留或排除的属性,包括关联对象里的嵌套属性。
比如针对你的Question模型,你可以这么写:
// api/models/Question.js module.exports = { attributes: { title: { type: 'string' }, choices: { collection: 'choice', via: 'question' } }, toJSON: function() { const obj = this.toObject(); // 移除Choice对象里的question关联,避免嵌套循环 if (obj.choices) { obj.choices = obj.choices.map(choice => { delete choice.question; return choice; }); } // 也可以直接排除整个不需要的属性,比如 delete obj.someInternalField; return obj; } };
方法二:配置蓝图的自动关联(populate)选项
Sails的蓝图默认会自动返回关联数据,你可以全局或者针对单个模型调整这个行为:
全局配置
修改config/blueprints.js,全局关闭自动关联,这样所有默认REST接口都不会返回关联数据(除非你手动通过populate参数指定):
// config/blueprints.js module.exports.blueprints = { populate: false };
单个模型配置
如果只想针对某个模型关闭自动关联,直接在模型的关联字段里设置:
// api/models/Question.js module.exports = { attributes: { title: { type: 'string' }, choices: { collection: 'choice', via: 'question', populate: false // 这个关联默认不被自动返回 } } };
方法三:自定义蓝图控制器动作
如果上面的方案不够灵活,你可以完全接管某个REST接口的逻辑,自己写查询和返回逻辑,做到100%的控制。
比如复制默认的find动作到QuestionController里,自定义返回内容:
// api/controllers/QuestionController.js module.exports = { find: async function(req, res) { try { // 只返回Question的id、title,以及Choice的id、text,排除嵌套的question关联 const questions = await Question.find() .select(['id', 'title']) .populate('choices', { select: ['id', 'text'], omit: ['question'] }); return res.json(questions); } catch (err) { return res.serverError(err); } } };
这样默认的GET /question接口就会使用你自定义的逻辑返回数据。
方法四:查询时使用
select/omit选项 在查询语句里直接指定要返回(select)或排除(omit)的属性,这个适合在自定义动作或服务里使用:
// 示例:只返回Question的核心字段,且排除Choice的question关联 const questions = await Question.find({ select: ['id', 'title'] }).populate('choices', { omit: ['question'] });
根据你的实际需求选择合适的方式就行——如果想全局统一处理,用蓝图配置或toJSON();如果需要针对特定接口做精细控制,自定义控制器动作或者查询选项是更好的选择。
内容的提问来源于stack exchange,提问作者Philip Feldmann
相关产品推荐
相关产品推荐

