Я являюсь фронтендером и делаю свой первый API с RBAC на основе Express + MongoDB. Мне нужно постобработать разрешения роли, которые у меня есть с помощью функции ожидания. Пример (этот код отлично работает):
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 с обратными вызовами неверно. Замена async / await на Promises неприемлема в моей ситуации. Но что мне делать, чтобы получить нужный мне результат?





Постобработка данных производится стандартным методом .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);
}
}