7

これは純粋なベストプラクティスの質問です。私はNodeとMongooseにかなり慣れていません。私はこのテクノロジーが大好きで、自分が構築しているアプリ用のJSONベースのAPIを構築するプロジェクトに取り組んできました。

データベースからオブジェクトをフェッチするときに、コードを継続的に繰り返していることがわかりました。例えば:

Playlist.findById(req.params.id, function(err,playlist){
  if (err)
    return res.json({error: "Error fetching playlist"});
  else if (!playlist)
    return res.json({error: "Error finding the playlist"});

  //Actual code being performed on the playlist that I'm fetching
});

関数呼び出しの先頭でのエラー処理は、データベースへの呼び出しごとにそのコードを繰り返さなければならないので面倒です...またはそう思います。

私は次のようなコールバックを使用することを考えました:

var fetchCallback = function(err,objOrDoc,callback){
  //Handle the error messages
  callback(objOrDoc);
};

ただし、フェッチを実行する前にコールバック関数を定義する必要があるため、このアプローチではシーケンシャルフローが台無しになります。したがって、多くのデータベースクエリをチェーン化した場合、コールバックを逆の順序で配置する必要があります。これは、クリーンコーディングの観点からは理想的とはほど遠いものです。

誰かがこの問題に遭遇し、繰り返しを減らすためのベストプラクティスを持っているかどうか疑問に思います。

私もExpressフレームワークを使用しているので、Expressでそれを処理するための便利な方法があれば、私も知りたいと思います。

4

1 に答える 1

12

ここで試すことができる興味深いアプローチがいくつかあります。

最も単純なのは、オブジェクトをロードし、エラー状態で出力を処理する関数を単純に持つことです。

fetchResource = function(model, req, res, callback) {
  model.findById(req.params.id, function(err, resource) {
    if (err)
      return res.json({error: "Error fetching " + model.toString()});
    else if (!playlist)
      return res.json({error: "Error finding the " + model.toString()});

    callback(resource);
  });
};

app.on('/playlists/1', function(req, res) {
  fetchResource(Playlist, req, res, function(playlist) {
    // code to deal with playlist.
  });
});

それはまだかなりの重複なので、これをミドルウェアに移そうとするかもしれません。

ルートミドルウェア

ルートは、1つ以上の追加のコールバック(または配列)をメソッドに渡すことにより、ルート固有のミドルウェアを利用できます。この機能は、アクセスの制限、ルートで使用されるデータのロードなどに非常に役立ちます。

今、私はこれをテストしておらず、少し手が震えています(読み取り:擬似コード)が、それはまともな例として役立つはずだと思います。

// assuming a URL of '/playlist/5' or '/user/10/edit', etc.

function loadResource(model) {
  return function(req, res, next) {
    model.findById(req.params.id, function(err, resource) {
      if (err)
        return res.json({error: "Error fetching " + model.toString()});
      else if (!resource)
        return res.json({error: "Error finding the " + model.toString()});

      req.resource = resource;
      next();
    });
  }
}

app.get('/playlist/:id', loadResource(Playlist), function(req, res) {
  var playlist = req.resource;
  ...
});

app.get('/user/:id', loadResource(User), function(req, res) {
  var user = req.resource;
  ...
});

エクスプレスソースには、このパターンのかなり良い例が含まれており、ドキュメントのミドルウェアセクション(特に「ルートミドルウェア」の下)でさらに詳しく説明されています。

于 2012-05-06T18:19:41.097 に答える