2017-01-18 2 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); 
    }); 
}); 

Контроллеры/api.js

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 в то время как вы используете обратные вызовы в контроллере. Я предлагаю вам изменить функцию getCars, чтобы вернуть Promise. Не знаю, что ODM/ORM вы используете, но это может выглядеть как что-то вроде этого:

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

Спасибо за ответ, вы правы, я ожидаю обещания в server.js, поэтому он не сработал. Является ли использование обещаний стандартным способом обработки DB-контроллера - отношения маршрутизатора в express? Я в основном ищу правильный шаблон, я не обязательно привязан к обещаниям. – finspin

+0

Одним из недостатков этого подхода было бы то, что мне пришлось бы обрабатывать ошибки для getCars в каждом маршрутизаторе, не так ли? – finspin

+1

Обратные вызовы - это старый способ обработки async в 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

Вы не использовали обещание правильно. Одна хорошая структура - просто написать определения функций в modules.exports, как это module.exports = {getCars: getCarsAsync} и написать всю логику в функции getCarsAsync –

+0

Как бы вы очистили сообщение об ошибке из базы данных с помощью этого решения? Допустим, вы хотите дать 400, если вы попытаетесь добавить новую строку в таблицу, где есть уникальный контраст? Не будет ли ваше решение возвратить общее 500? Я предлагаю, чтобы его обработка HttpStatus выполнялась вне функции базы данных, чтобы ее можно было повторно использовать. –

+1

@ R.Gulbrandsen. У вас практически будет 3 - 4 разных типа кодов ошибок. Что вы можете сделать: используйте 'next' третий параметр функции маршрута и configure express, чтобы иметь собственное промежуточное программное обеспечение для обработки' next() '. Затем вы передадите сообщение об ошибке как «next ({« error »:« missing »,« description »:« some error message »})« промежуточное ПО должно отображать отсутствующее значение до 404, и, следовательно, api получит статус 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); 
     } 
     }); 
    }); 
    } 
}; 
Смежные вопросы