目前,我正在使用Node JS&amp ;;中的REST API。表达。我必须为API中的每个资源创建一个链接,例如之外的示例。
{
"id": "20281",
"title": "test",
"body": "test",
"date": "2017-11-14 09:01:35",
"_links": {
"self": {
"href": "https://docent.cmi.hro.nl/bootb/demo/notes/20281"
},
"collection": {
"href": "https://docent.cmi.hro.nl/bootb/demo/notes/"
}
}
},
我知道我可以在我的控制器中处理这个,因为req对象可用。但最好在我的模型中创建一个虚拟字段来动态创建链接而不是将其保存在数据库中。
最好的方法是什么?
DB: MongoDB ODM: Mongoose
答案 0 :(得分:1)
有很多方法可以做到这一点,而且您还没有描述过您的数据库或ORM等,但暗示您的术语与这些行有关。
最简单的做法就是假设这不是存储的关注点,而是将您全局应用于api的内容,以便所有路由都应用它。这可能是中间件的形式:
router.use((req, res, next) => {
if (res.data) { // if you do it this way, none of your routes will actually do a res.send, but instead will put their data into res.data and rely on another middleware to render or send it
res.data._links = {
self: calculateSelf(req, res.data),
collection: calculateCollection(req, res.data)
};
}
});
鉴于此,这两个链接计算器可以使用一些标准模式或正则表达式来确定链接应该是什么样的。
或者,如果您正在使用Mongoose,则可以覆盖toJSON以填充您希望在线路上发送的任何模型中的链接,但这意味着您的模型应该知道根应用程序URL是什么,我不推荐。
虚拟字段实施:
YourSchema.virtual('links').get(() => {
return {
self: 'http://example.com/api/v1.0/schema/' + this._id,
collection: 'http://example.com/api/v1.0/schema/'
};
});
为了实现这一目标,您必须将{ virtuals: true }
传递给toObject()
或toJSON()
,或将其设置为全局猫鼬配置以始终显示虚拟。正如我之前所说,我真的不建议这样做,因为它要求模式可以访问和了解基本URL,这可以在不同环境之间进行更改。如果(正如您的架构所暗示的)模型代表一个网页,那么URL模板可能是与模型实际相关的东西,但在大多数域中都不是这样的,所以我就是这样。推荐中间件方法。
答案 1 :(得分:0)
如果您使用的是猫鼬,则可以使用virtual属性创建非持久字段,以下是一个示例:
var MySchema = new Schema({
id: Number,
title: String,
body: String,
date: Date
});
MySchema.virtual('links').get(function () {
return {
self: {
href: 'https://docent.cmi.hro.nl/bootb/demo/notes/' + this.id
},
collection: {
href: 'https://docent.cmi.hro.nl/bootb/demo/notes'
}
}
});
var My = mongoose.model('My', MySchema);
或您可以在查找中间件(post hooks)之后使用,例如:
var MySchema = new Schema({
id: Number,
title: String,
body: String,
date: Date
});
MySchema.post('find', function(doc) {
doc.links = {
self: {
'href': 'https://docent.cmi.hro.nl/bootb/demo/notes/' + doc.id
},
collection: {
'href': 'https://docent.cmi.hro.nl/bootb/demo/notes/'
}
}
});
var My = mongoose.model('My', MySchema);