2017-07-07 10 views
0

私はNode.js、Express、Mongoose/MongoDBでWebアプリケーションを構築しています。マングース組織/クラス構造を作成していますか?

私が持っていた1つの質問は、どのようにモンゴースに関連する方法を正しく構成し、構造化するかということでした。ルート内でMongooseの機能を呼び出す必要がありますが、すべての例では、Mongooseの呼び出しを使用して、プロトタイプで別のファイルやクラスを構成することなく表示しています。

IE。スキーマを設定すると、私はロジックと機能性に関連するヘルパーファイル内のマングースのCRUD機能を入れて、私のルートでそれらを呼び出したいルート

SiteModel.find({}, function(err, docs) { 
if (!err){ 
    console.log(docs); 
    process.exit(); 
} else {throw err;} 
}); 

でマングースを呼び出します。私はマングースと別のクラスのメソッドを使用する場合は、何も値を返さない(または起因する非同期性のために、私は結果を使用することができません)され

//Router file 
var myService = require('../helpers/ServiceStatus'); 

router.get('/', authService.isLoggedIn, function(req,res){ 

    var serviceObject = new myService(); //Initialize class with Mongoose functions 

    async.parallel({ 
     modelAFind: function(cb){ 
      //Mongoose class method is called 
      var response= serviceObject.getAllServiceDetails(); 
      cb(null, response); 
     }, 
     modelBFind: function(cb){ 
      cb(null, 2); //filler 
     } 
    }, function(results){ 
     console.log("Results of query: " + results); 
    }); 

スニペット私はサービスオブジェクトを作成し、私のマングースクラスから:

//ServiceStatus.js 
//Constructor 
function ServiceStatus() { 

} 

ServiceStatus.prototype.getAllServiceDetails = function(){ 

    var query = SiteModel.find({}); 
    var promise = query.exec(); 

    promise.then(function (doc) { 
     return doc; 
    }); 
}; 

非同期に対処する最良の方法は、Mongooseロジックを持つ別々のヘルパーファイルを構造化し、それらをルートで呼び出すことです:約束事、コールバック付き関数など?ありがとう。

*編集 - 追加されたスキーマだから

var mongoose = require('mongoose'); 
var Schema = mongoose.Schema; 

// set up a mongoose model 
module.exports = mongoose.model('SiteModel', new Schema({ 

    id: String, 
    service: {type: String, unique: true, required: true}, 
    status: String, 
    settings: Object, 
    lastCheck: String 

} 

,{ 
    timestamps: true 
})); 

答えて

0

ファイル私たちもあなたのコードを整理する「最良の」道に入る前に、あなたが不足している親指の重要なルールのカップルが、あります。

  1. 非同期メソッドを扱うときは、常に (およびそれらの呼び出しコード)をasyncとして処理する必要があります。あなたの例では、 getAllServiceDetails()関数は約束を返さず、 もコールバックを実行しないので、そのコンテキストを失います。
  2. 同じロジックスタック内のプロミスとコールバックの両方を使用すると、脳に認知負荷が追加されます( )。 1つのスタイルで試してみてください。可能であれば可能な限り です。

整理するための最良の方法として、私はこのケースでは、全体のサービスクラスを引き出しないで強く見てね、と代わりにマングースのプラグインを書く、あるいは単にマングーススキーマ自体を拡張を見てください。プラグインは、複数のモデルに同じコードを書く場合に便利です。この例ではないと仮定して、SiteSchemaのみの例を続けます。あなたのスキーマのコードは、私はあなたが本当に単にあなたのルーティングコードでSiteModel.find(...)を呼び出していないことで節約していますが、引数のためにあなたができるどちらかはよく分からないので、ここでは表示されません。

必要がなくなります
SiteSchema.statics.list = function(cb) { 
    SiteSchema.find({}, cb); 
} 

/** snip **/ 
modelAFind: function(cb){ 
     //Mongoose class method is called 
     var response= serviceObject.list(cb); 
    }, 

あなたはノードの最新バージョンのいずれかを使用している場合、あなたはまた、アクセス権を持っている:呼び出し元のコードでは、空のオブジェクトを渡しすることが、コードを呼び出すと、まだこのように見ているということから、 async/await構文に変更してください。私の例がテストされていませんが、それはこのようなものになります。

SiteSchema.statics.list = async function() { // note the 'async' keyword 
    // latest versions of Mongoose, this returns a Promoise 
    return SiteSchema.find({}); 
} 

を次に、あなたの消費コードが

/** snip **/ 
modelAFind: function(cb){ 
     //Mongoose class method is called 
     var response= await serviceObject.list(); // note 'await' keyword 
     cb(null, response); 
    }, 

はまた、私はエラー処理を追加していないことに注意することができます。非同期/あなたがtry ... catchを使うのを待っています。

+0

こんにちはポール、これは素晴らしい情報です。モデルのスキーマファイルを添付しました。具体的な "getter"と "setter"クエリでは、ファイルを分割するのではなく、Mongooseスキーマにすべての関数を記述しますか? – Jacob

+0

はい、間違いなくそれを行うでしょう。私は、複数のモデルにまたがるロジックのサービスクラスを作成するだけです。 – Paul