MEANスタック(MongoDb、Express.js、Angular.js、Node.js)を使用し、Mongoose ODMを利用して書かれた非常に基本的なRESTfulサービスがあります。
Product
スキーマ
var productSchema = new mongoose.Schema({
name: {type: String, required: true, maxlength: 250},
_prices: [{
amount: {type: Number,required: true,min: 0.0},
date: {type: Date, required: true, default: Date.now}
}]
});
productSchema
.virtual('price')
.get(function () {
var price = this._prices[this._prices.length - 1];
return price !== undefined ? price.amount : undefined;
});
productSchema.methods.setPrice = function (amount) {
this._prices.Push({amount: amount});
};
_prices
配列とprice
仮想プロパティの目的は、価格履歴の監査証跡を保存することです。
通常のGET
、POST
、PUT
およびDELETE
をサポートする/products
のRESTfulインターフェイスがあります。
私のシステムでは、管理者はPOST
、PUT
、およびDELETE
を許可されていますが、匿名アクセスの場合に問題が発生します。匿名ユーザーはGET
のみを許可されていますが、履歴を表示できるのは管理者だけなので、GET
レスポンスには_prices
フィールドを含めないでください。
匿名として
{
name: "Widget",
price: "5.99"
}
管理者として
{
name: "Widget",
price: "5.99",
_prices: [
{price: "7.25", date: "2015-02-28"},
{price: "5.99", date: "2016-01-09"}
]
}
MEANスタックに関して読んだチュートリアルの大部分は、常にマングースモデルを直接返すことを示しています。
exports.getAll = function(request, response) {
Product.find({}, '-_prices', function (err, products) {
res.json(200, products);
});
};
これはproducts
コントローラーから回避するのは非常に簡単ですが、このフィルターロジックがコントローラーにあるため、これは非常に見当違いであり、スキーマに新しいフィールドを追加する場合は脆弱であることがわかります。コントローラに戻って、将来フィールドを公開しないようにします。
また、リクエストの検証を行う、別の方法についても質問があります。ほとんどのチュートリアルでは、ユーザー入力をそのまま受け入れて、マングースの検証を失敗させているようです。
exports.post = function(request, response) {
var product = new Product(request.body)
product.save(function(error, product) {
if (error) {
return response.json(422, error);
}
response.send(201);
});
};
ASP.NET WebApiに慣れているため、これに対する私の見方は少し歪んでいます。私はおそらく、リクエストに対して個別のビューモデルを作成し、レスポンスに対して異なるビューモデルを作成し(認証されているかどうかに応じて)、リクエストのビューモデルで入力検証を行い、エンティティ内で不変の検証のみを行います。ただし、MEANスタックの方法で実行していることを確認します。
私の質問は次のとおりです。
入力の検証はmongooseの検証のみに依存する必要がありますか、それともmongooseに到達する前に独自に作成する必要がありますか?
出力フィルタリングの場合、Product
を受け入れ、ユーザーの管理者であるかどうかに応じて、ユーザーのコンテキストに応じてビューモデルを返すセキュリティ/フィルタリングモジュールを作成する必要がありますか?
フィルタリングを行うには、toJSON
の動作(マングースで拡張可能です)をオーバーライドする必要がありますか?
コントローラとマングースの間に抽象レイヤーを作成する必要がありますか?
私の最初の考えは、マングース自体は責任が多すぎるということですが、それが最善のアプローチである場合は、使用を避けたくありません。
- 入力の検証はmongooseの検証のみに依存する必要がありますか、それともmongooseに到達する前に独自に作成する必要がありますか?
サービスの種類によっては、DB内ではなく、DBモジュールとHTTPモジュールの間でチェックを行う必要があると思います。
- 出力フィルタリングの場合、製品を受け入れ、管理者であるかどうかに応じて、ユーザーのコンテキストに応じてビューモデルを返すセキュリティ/フィルタリングモジュールを作成する必要がありますか?
モデルからHTTPインターフェースに何かが直接返される方法が嫌いですが、ここでは最も簡単な方法を使用できます。必要に応じて、リクエストハンドラーで権限を確認し、余分なフィールドを削除してオブジェクトを調整します。これは行数が少なくなります。
- フィルタリングを行うには、toJSONの動作(Mongooseでは拡張可能です)をオーバーライドする必要がありますか?
番号。
- コントローラとマングースの間に抽象レイヤーを作成する必要がありますか?
データモデルレイヤーですか?いいえ。コントローラでこれを「制御」します。