猫鼬。等待数据的后处理
Mongoose. Postprocessing of awaiting data
我是前端开发人员,我第一次使用基于 Express + MongoDB 的 RBAC API。我需要对通过 await 函数获得的 Role 权限进行后处理。示例(此代码效果很好):
export async function getRoleById(req, res) {
try {
const role = await Role.findById(req.params.id)
.populate('permissions');
return res.status(HTTPStatus.OK).json(role);
} catch (err) {
return res.status(HTTPStatus.BAD_REQUEST).json(err);
}
}
结果:
{
"id": "5c27d6bfc51081331411dcd8",
"name": "writer2",
"permissions": [
{
"id": "5c27c43e2eb0c279ccd945ef",
"action": "create",
"subject": "task"
},
{
"id": "5c27c4532eb0c279ccd945f1",
"action": "read",
"subject": "task"
}
]
}
但我需要另一种格式的权限:
{
"id": "5c27d6bfc51081331411dcd8",
"name": "writer2",
"permissions": [
[ "create", "article" ],
[ "list", "user" ]
]
}
所以我尝试这样做:
export async function getRoleById(req, res) {
try {
const role = await Role.findById(req.params.id)
.populate('permissions')
.then((foundRole) => {
foundRole.permissions = foundRole.permissions.map(item => [ item.action, item.subject]);
return foundRole;
});
return res.status(HTTPStatus.OK).json(role);
} catch (err) {
return res.status(HTTPStatus.BAD_REQUEST).json(err);
}
}
将 then 替换为 exec 并没有改变这种情况。执行此代码后,我得到响应 200,但没有任何数据。空白页面而不是带有角色数据的对象。
我阅读了很多关于 Mongoose 查询的文章,以及为什么将 async/await 与回调一起使用是不正确的。在我的情况下,用 Promises 替换 async/await 是不可接受的方式。但是我应该怎么做才能得到我需要的结果呢?
数据后处理通过 Schema 的标准方法 .toJSON()
进行。所以我们可以创建自己的方法,例如 .toMyJSON()
或重新定义标准方法。我选择第二种方式
在文件 role.model.js
中,我放置角色架构的位置:
import mongoose, { Schema } from 'mongoose';
import uniqueValidator from 'mongoose-unique-validator';
import User from '../users/user.model';
const RoleSchema = new Schema({
/* here goes Schema */
});
/* Redefine standard method toJSON */
RoleSchema.methods = {
toJSON() {
return {
id: this._id,
name: this.name,
permissions: this.permissions.map(item => [item.action, item.subject]),
};
},
};
RoleSchema.statics = {
/* Here goes static methods of Schema */
};
export default mongoose.model('Role', RoleSchema);
现在我们可以使用这个方法:
export async function getRoleById(req, res) {
try {
const role = await Role.findById(req.params.id).populate('permissions');
return res.status(HTTPStatus.OK).json(role.toJSON()); // Here we use toJSON method.
} catch (err) {
return res.status(HTTPStatus.BAD_REQUEST).json(err);
}
}
我是前端开发人员,我第一次使用基于 Express + MongoDB 的 RBAC API。我需要对通过 await 函数获得的 Role 权限进行后处理。示例(此代码效果很好):
export async function getRoleById(req, res) {
try {
const role = await Role.findById(req.params.id)
.populate('permissions');
return res.status(HTTPStatus.OK).json(role);
} catch (err) {
return res.status(HTTPStatus.BAD_REQUEST).json(err);
}
}
结果:
{
"id": "5c27d6bfc51081331411dcd8",
"name": "writer2",
"permissions": [
{
"id": "5c27c43e2eb0c279ccd945ef",
"action": "create",
"subject": "task"
},
{
"id": "5c27c4532eb0c279ccd945f1",
"action": "read",
"subject": "task"
}
]
}
但我需要另一种格式的权限:
{
"id": "5c27d6bfc51081331411dcd8",
"name": "writer2",
"permissions": [
[ "create", "article" ],
[ "list", "user" ]
]
}
所以我尝试这样做:
export async function getRoleById(req, res) {
try {
const role = await Role.findById(req.params.id)
.populate('permissions')
.then((foundRole) => {
foundRole.permissions = foundRole.permissions.map(item => [ item.action, item.subject]);
return foundRole;
});
return res.status(HTTPStatus.OK).json(role);
} catch (err) {
return res.status(HTTPStatus.BAD_REQUEST).json(err);
}
}
将 then 替换为 exec 并没有改变这种情况。执行此代码后,我得到响应 200,但没有任何数据。空白页面而不是带有角色数据的对象。
我阅读了很多关于 Mongoose 查询的文章,以及为什么将 async/await 与回调一起使用是不正确的。在我的情况下,用 Promises 替换 async/await 是不可接受的方式。但是我应该怎么做才能得到我需要的结果呢?
数据后处理通过 Schema 的标准方法 .toJSON()
进行。所以我们可以创建自己的方法,例如 .toMyJSON()
或重新定义标准方法。我选择第二种方式
在文件 role.model.js
中,我放置角色架构的位置:
import mongoose, { Schema } from 'mongoose';
import uniqueValidator from 'mongoose-unique-validator';
import User from '../users/user.model';
const RoleSchema = new Schema({
/* here goes Schema */
});
/* Redefine standard method toJSON */
RoleSchema.methods = {
toJSON() {
return {
id: this._id,
name: this.name,
permissions: this.permissions.map(item => [item.action, item.subject]),
};
},
};
RoleSchema.statics = {
/* Here goes static methods of Schema */
};
export default mongoose.model('Role', RoleSchema);
现在我们可以使用这个方法:
export async function getRoleById(req, res) {
try {
const role = await Role.findById(req.params.id).populate('permissions');
return res.status(HTTPStatus.OK).json(role.toJSON()); // Here we use toJSON method.
} catch (err) {
return res.status(HTTPStatus.BAD_REQUEST).json(err);
}
}