続行する前に、ユーザーが特定のリソースへのアクセスを許可されているかどうかを確認する必要があるルートを持つ Web アプリケーションを想像してください。「認証済み」チェックは、データベース呼び出しに依存しています。
各ルートで、次のことが考えられます。
authorizeOwnership(req, res)
.then(function() {
// do stuff
res.send(200, "Yay");
});
authorizeOwnership()
各ルートで明示的に処理する必要がないように、関数で 403 (アクセス拒否) および 500 (データベース クエリ エラーなど) の応答を処理する必要があります。
データベースにクエリを実行して所有権を確認できる機能があります。
function confirmOwnership(resourceId, userId) {
// SequelizeJS... returns a bluebird promise
return Resource.find({
where: {id: resourceId, userId: userId}
})
.then(function(resource) {
if(!resource) {
return null; // no match for this resource id + user id
} else {
return resource;
}
});
}
これは次に使用されauthorizeOwnership
ます。
function authorizeOwnership(req, res) {
var rid = parseInt(req.params.rid, 10),
userId = parseInt(req.authInfo.userid, 10);
return new Promise(function(resolve, reject) {
confirmOwnership(rid, userId)
.then(function(resource) {
if(resource === null) {
res.send(403, "Forbidden");
// Note: we don't resolve; outer handler will not be called
} else {
resolve(resource);
}
})
.catch(function(err) {
console.log(err);
res.send(500, "Server error");
// Note: we don't resolve; outer handler will not be called
});
});
}
このシナリオでは、意図的に一部のコード パスでreject()
orを呼び出しません。その場合、エラーを処理する必要があるため (またはcheck inを使用して) resolve()
、「外部」ルート ロジック ( を呼び出しているコードauthorizeOwnership()
) がより複雑になります。.catch()
null
.then()
ただし、次の 2 つの点で少し緊張します。
によって返された promise
authorizeOwnership()
がエラー シナリオで解決されなくても問題ありませんか? 遅延やメモリリークの原因になりますか?confirmOwnership()
「一致するリソースが見つかりません」と言ってnullで解決し、それをエラーとして扱うのは論理的に正しいauthorizeOwnership()
ですか? 私の最初の試行では、一致するリソースがない場合に promise を拒否しましconfirmOwnership()
たが、これ (403 のケース) と実際のエラー (500 のケース) を区別するのが難しいため、事態はより複雑になりました。