2017-01-18 12 views
0

データベース操作を処理するコントローラを再利用しようとしています。私は自分のアプリケーションを構造化するのに苦労しています。ここで私が持っているものだ:/データベースコントローラを再利用する方法

server.js

var apiController = require('./controllers/api'); 

router.get('/cars', function (req, res) { 
    // get all cars from DB and render view 

    apiController.getCars().then(function (cars) { 
     res.render('index', {cars: cars}); 
    }); 
}); 

router.get('/api/cars', function (req, res) { 
    // get all cars from DB and return JSON 

    apiController.getCars().then(function (cars) { 
     res.json(cars); 
    }); 
}); 

コントローラ

module.exports = { 

    getCars: function() { 
     db.collection('cars').find().toArray(function (err, cars) { 
      if (err) throw err; 
      return cars; 
     }); 
    }, 

    // tried also something like this but this doesn't really work 
    // for my use case because I don't want to attach any particular 
    // res to the function 
    getCars: function (req, res, next) { 
     db.collection('cars').find().toArray(function (err, cars) { 
      if (err) throw err; 
      res.json(cars); 
     }); 
    }, 
}; 

答えて

0

あなたの現在の問題は、あなたがserver.jsで戻りとして約束を期待していることであるapi.jsながら、コントローラーでコールバックを使用します。 Promiseを返すように関数getCarsを変更することをお勧めします。あなたが使用しているものODM/ORMか分からないのですが、それはこのようなもののようになります。

getCars: function() { 
    return db.collection('cars').find(); 
}, 
+0

答えをいただきありがとうございます。私はserver.jsで約束を期待しています。それが問題なのです。エクスプレスでDBコントローラ - ルータ関係を処理する標準的な方法を約束して使用していますか?私は基本的に正しいパターンを探しています、私は約束に必ずしも付いていません。 – finspin

+0

このアプローチの欠点は、各ルータでgetCarsのエラー処理を行う必要があることでしょうか? – finspin

+1

コールバックは、JavaScriptで非同期を処理する古い方法です。新しいことを約束します。だから私はあなたがそれについてあまりにもひどく感じないなら、約束を使用することをお勧めします。 –

0
server.js 

var apiController = require('./controllers/api'); 
    router.get('/cars', apiController.getCars); 



controllers/api.js 

    function getCarsAsync(req, res, next){ 
     db.collection('cars').find().then(function(carsData){ 
      if(carsData){ 
       return res.send(carsData); 
      } 
      else{ 
       return res.status(401).send('User is not authorized'); 
      } 
     }).catch(function(err){ 
      return next(err); 
     }); 
    } 

    module.exports = { 
     getCars: getCarsAsync 
    }; 
+0

あなたは約束を正しく使用していませんでした。 1つの良い構造は、このようなmodule.exportsに関数定義を書くことです。 module.exports = {getCars:getCarsAsync} getCarsAsync関数内のすべてのロジックを書きます。 –

+0

このソリューションを使用してデータベースからエラーメッセージをどのようにクリーンアップしますか?独自の拘束があるテーブルに新しい行を追加しようとすると、400を与えたいとしますか?あなたのソリューションは一般的な500を返しますか?彼のHttpStatusの処理はデータベース機能の外で行われ、再利用できることをお勧めします。 –

+1

@ R.Gulbrandsen実際には3〜4種類のエラーコードがあります。あなたができることは次のとおりです:ルート関数の 'next'第3引数を使い、 'next()'を扱うカスタムミドルウェアを持つようにexpressを設定します。ミドルウェアは404への欠落をマップしなければならないため、適切なエラーメッセージを表示した状態で404を取得します( ' 。 –

0

server.js

var apiController = require('./controllers/api'); 
router.get('/cars', function (req, res) { 
    apiController.get('cars').then(function (cars) { 
     res.render('index', {cars: cars}); 
    }); 
}); 

router.get('/api/cars', function (req, res) { 
    apiController.get('cars').then(function (cars) { 
     res.json(cars); 
    }); 
}); 

コントローラ/ api.js

var Promise = require('bluebird'); 
module.exports = { 
    get: function (modelName) { 
    return new Promise(function(resolve,reject){ 
     return db.collection(modelName).find().toArray(function(err, models){ 
     if (err) { 
      return reject(err); 
     } 
     else { 
      return resolve(models); 
     } 
     }); 
    }); 
    } 
}; 
関連する問題