基于 GET 参数的 Express/Mongoose REST API 路由

Posted

技术标签:

【中文标题】基于 GET 参数的 Express/Mongoose REST API 路由【英文标题】:Routing based on GET parameters for Express/Mongoose REST API 【发布时间】:2014-03-17 20:02:56 【问题描述】:

在使用 Mongo + Express 设计 REST API 时,我正在努力思考如何处理更复杂的查询。不幸的是,我能找到的所有例子都太简单了。这是一个用于此问题的简单示例。我有组,也有用户。在每个组内,有成员和 1 个领导者。为了简单起见,我将排除中间件和发布/放置/删除功能。

路线看起来像这样:

app.get('/groups', groups.all);  
app.get('/groups/:groupId', groups.show);  
app.param('groupId', groups.group); 

控制器看起来像这样:

/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
   Group = mongoose.model('Group'), 
   _ = require('lodash');


/**
* Find group by id
*/
exports.group = function(req, res, next, id) 
    Group.load(id, function(err, group) 
       if (err) return next(err);
       if (!group) return next(new Error('Failed to load group ' + id));
       req.group = group;
       next();
    );
;

/**
* Show a group
*/
exports.show = function(req, res) 
   res.jsonp(req.group);
;

/**
* List of Groups
*/
exports.all = function(req, res) 
   Group.find().sort('-created').populate('user', 'name username').exec(function(err, groups) 
    if (err) 
        res.render('error', 
            status: 500
        );
     else 
        res.jsonp(groups);
    
   );
;

然后模型看起来像这样:

var mongoose = require('mongoose'),
Schema = mongoose.Schema;

/**
* Group Schema
*/
var GroupSchema = new Schema(
   created: 
       type: Date,
       default: Date.now
   ,
   updated: 
       type: Date,
       default: Date.now
   ,
   enableScores: 
       type: Boolean,
       default: false
   ,
   name: 
       type: String,
       default: '',
       trim: true
   ,
   creator: 
       type: Schema.ObjectId,
       ref: 'User'
   ,
   commissioner: 
       type: Schema.ObjectId,
       ref: 'User'
   
);

/**
* Validations
*/
GroupSchema.path('name').validate(function(name) 
   return name.length;
, 'Name cannot be blank');

/**
* Statics
*/
GroupSchema.statics.load = function(id, cb) 
    this.findOne(
       _id: id
    )
    .populate('creator', 'name username')
    .populate('commissioner', 'name username') 
    .exec(cb);
;

mongoose.model('Group', GroupSchema);

如果我想根据专员字段查询 REST API 怎么办?还是创建者、名称或创建的字段?这是否可以使用 Express 的路由,如果可以,是否有最佳实践?

似乎与其处理这些独特情况中的每一个,不如使用一些通用的东西来返回基于 req.params 匹配的所有组,因为如果模型稍后发生更改,我将不需要更新控制器。如果这是这样做的方法,那么也许修改 all() 函数以根据 req.params 进行查找是解决方案吗?因此,如果未提供任何内容,则它会返回所有内容,但是当您提供更多获取参数时,它会深入了解您要查找的内容。

【问题讨论】:

【参考方案1】:

我建议使用req.query 来匹配架构中的字段。 如果您发送类似/groups?name=someGrp&enableScores=1 的请求,req.query 将如下所示...

name: "someGrp", enableScores: 1

您可以像这样将此对象传递给 find 方法...

Group.find(req.query, callback);

这种方法适用于简单的属性匹配查询,但对于比较和数组属性等其他事情,您必须编写额外的代码。

【讨论】:

谢谢。这正是我想要的。 app.get('/groups', groups.all); 还是一样吗?

以上是关于基于 GET 参数的 Express/Mongoose REST API 路由的主要内容,如果未能解决你的问题,请参考以下文章

sql-labs SQL注入平台-第1关Less-1 GET - Error based - Single quotes - String(基于错误的GET单引号字符型注入)

sql-labs SQL注入平台-第1关Less-1 GET - Error based - Single quotes - String(基于错误的GET单引号字符型注入)

sql-labs SQL注入平台-第1关Less-1 GET - Error based - Single quotes - String(基于错误的GET单引号字符型注入)

将基于缓存 Django 类的视图响应与请求中的参数绑定

请求库之requests库

Get与Post的小知识