2017-08-28 10 views
0

私はいくつかの文脈から始めます: 私はユーザーを管理するためのルートを含むRESTfulなAPIサーバーを持っています。例えばexpressでreq.paramsを再割り当てすることはできますか?

PUT .../users/:id/profile

は、当社の認証フローの一環として、我々は、ユーザーの身元を確認し、私たちのIDPから取得したIDを持つURLにIDを比較します。

私がやっていることは、「私の」代替アプローチを実装することです。ユーザーは、自分のIDをURLに提供するのではなく、代わりに 'me'を提供するだけで、そのIDに基づいてIDから取得したidでIDを再割り当てすることができます。私はGoogleがいくつかのAPIでこれを行うのを見た。例えば。

req.params.id = req.params.id === 'me' 
    ? session.id 
    : req.params.id 

これは、私が上の読みのビットをやったので、働いていませんでした。これまでのところ、私は修正req.paramsが前方に伝播することを前提と簡単に交換をしようとしてきた .../users/me/profile

それと明らかにreq.paramsは各ミドルウェア関数(.use()が呼び出されたとき)でビルドされているので、req.params.idの再割り当ては私が望むようにアプリ全体に伝播しません。

私たちのビジネスロジックはすべてreq.paramsからIDを取得しますので、私のビジネスロジックをすべてリファクタリングしないように上記の動作をする方法があるのだろうかと疑問に思っていましたか?

私はreq.paramsがurlの解析から構築されていることを理解しています。したがって、URLを変更することはオプションですか? 「私」をidに置き換える。 req.paramsに意図したとおりの値が設定されるようにします。もしそうなら、これはどのように達成できますか?

上記の「私」の交換行動を得るためのより良い方法があれば、私はすべて耳にします!

+0

...ユーザーのIDがURLに含まれていない場合は、他の場所に提供する必要があります。それ以外の場合、RESTfulアプリケーションはユーザーのIDをどのように知ることができますか? – blewherself

+0

はい、認証フローからIDを取得できます。しかし、問題はすべて私のロジックがIDのreq.params.idを検査することです。私がしようとしているのは、認証フローから受け取ったIDをreq.params.idに注入することです。 – Mitch

+0

入手しました。次に、 'req.params.id'を割り当てようとするとうまくいくはずです。テストしただけで、すべてがうまく見えます。つまり、必要なものを 'req.params.id'に割り当てることができます。/users/me/profileの新しいルートを作成しようとしましたか? – blewherself

答えて

1

グローバルミドルウェアは、(あなたがapp.use()router.use()を使用して追加すること)は、通常、パラメータを宣言任意の経路ハンドラのにも気づいていないので、req.paramsは通常でも移入されません。

ソリューションは、「インライン」修飾ミドルウェアに次のようになります。

app.put('/users/:id/profile', middleware, ...) 

しかし、それはすべてあなたのルートハンドラを書き換える必要であろう。

すでに正しく指摘するように、あなた URLを変更することができます。代わりに、特に各URLにマッチするので

app.use(function(req, res, next) { 
    if (req.url === '/users/me/profile') { 
    req.url = '/users/1234/profile'; 
    } 
    next(); 
}); 

app.put('/users/:id/profile', ...) 

、あなたがサブストリングマッチを行う、またはすべてのURLのその月のリストを使用することができます:idパラメータを含む(したがって、me識別子を含む可能性があります)。

私はちょうど(req.param()を使用して)これが機能する必要があることを実現:

router.param('id', function(req, res, next, id) { 
    if (id === 'me') { 
    req.params.id = '1234'; 
    } 
    next(); 
}); 

これは直接ルートハンドラ、またはマウントポイントのいずれかで、パラメータを宣言ルータに追加されなければなりません。

複雑例:

let childRouter = express.Router({ mergeParams : true }); 

childRouter.put('/profile', ...); 

let parentRouter = express.Router({ mergeParams : true }); 

parentRouter.use('/:id', childRouter); 

parentRouter.param('id', function(req, res, next, id) { 
    if (id === 'me') { 
    req.params.id = '1234'; 
    } 
    next(); 
}); 

app.use('/users', parentRouter); 

parentRouterはマウントポイント/:idを宣言しているので、それが解決する機能を取得する必要があります。

+0

申し訳ありませんが、もっと明確にする必要があります。はい、あなたが言及したようなルートハンドラーを使用しています。しかし、私はルーターをルーターにルーティングしています。私は/ users /:idのルータを持っています。ルータは/ profile等を探す別のルータに向いていますので、その時点でreq.urlは/ profileしか表示していません。私はoriginalUrlを修正しようとしましたが、うまく動作していないようです... – Mitch

+0

@Mitchは私の編集を参照してください、より堅牢なかもしれない書き換えの別の方法があります。 – robertklep

+0

今日のいくつかのテストとreq.param()アプローチは、魅力のように機能しましたか?どうもありがとうございました! req.param()内のreq.params.idの設定が他のミドルウェア内ではできない理由を完全に理解しているかどうかはわかりません。 – Mitch

関連する問題