我正在开发一个API,我们为各种GET返回的各个资源发送Last-Modified
日期标题。
当客户端在该资源上进行PUT / PATCH时,他们可以发送If-Unmodified-Since
标头以确保它们仅更新资源的最新版本。
支持这是一种痛苦,因为我希望我的应用程序响应以下用例:
有没有更好的方法使用Mongo执行此操作,不涉及进行3次单独的Mongo数据库调用以捕获可能的用例并返回相应的响应?
我想清理一下:
// the callback the handler is expecting from the model method below
callback(err, preconditionFailed, wasUpdatedBool)
// model method
var orders = this.db.client({ collection: 'orders' });
var query = { _id: this.db.toBSON(this.request.params.id) };
// does the order exist?
orders.findOne(query, function(err, doc) {
if(err) {
return callback(err);
}
if(!doc) {
return callback(null, null, false);
}
// are you updating the most recent version of the doc?
var ifUnModifiedSince = new Date(self.request.headers['if-unmodified-since']).getTime();
if(ifUnModifiedSince) {
query.lastModified = { $lte: ifUnModifiedSince };
orders.findOne(query, function(err, doc) {
if(err) {
return callback(err);
}
if(!doc) {
return callback(null, true);
}
//attempt to update
orders.update(query, payload, function(err, result) {
if(err) {
return callback(err);
}
if(!result) {
return callback(null, null, false);
}
return callback(null, null, result);
});
});
}
//attempt to update
orders.update(query, payload, function(err, result) {
if(err) {
return callback(err);
}
if(!result) {
return callback(null, null, false);
}
callback(null, null, result);
});
});
答案 0 :(得分:0)
您可能知道的查询太多了。一般的流程应该是:
if-unmodified-since
标题,并将其与文档的修改日期进行比较。问题412(如适用)所以,你的代码应该是这样的:
var orders = this.db.client({ collection: 'orders' });
var query = { _id: this.db.toBSON(this.request.params.id) };
orders.findOne(query, function(err, order) {
if(err) {
return callback(err); // Should throw a 500
}
if(!order) {
return callback(404);
}
if(self.request.headers['if-unmodified-since']) {
var ifUnModifiedSince = new Date(self.request.headers['if-unmodified-since']).getTime();
if(order.lastModified.getTime() > ifUnModifiedSince) {
return callback(412); // Should throw a 412
}
}
// Now do the update
orders.update(query, payload, function(err, result) {
if(err) {
return callback(err);
}
if(!result) {
return callback(null, null, false);
}
return callback(null, null, result);
});
});