NodeJS / Express: преобразование кода Mongoose в собственный код MongoDB - PullRequest
0 голосов
/ 21 сентября 2018

Я использовал учебник здесь , чтобы создать приложение, которое действует как служба, которая будет использоваться другими приложениями для взаимодействия с экземпляром MongoDB.Это руководство использует Mongoose и его концепцию модели для выполнения своей работы.Он также имеет статические входы и выходы для запроса и ответа, потому что ключи известны.Наконец, он не указывает имя коллекции.Однако мое требование состоит в том, чтобы сделать что-то действительно общее, с очень небольшими ограничениями.Я просто хочу что-то, что может быть вызвано для выполнения операций CRUD на экземпляре MongoDB с 4 или 5 маршрутами - по одному на каждую операцию CRUD, а затем, возможно, маршрут GET для получения спецификаций API, чтобы разработчики могли видетькаковы необходимые входные данные.Также хотелось бы, чтобы сам запрос указывал коллекцию и имя БД.Я сделал это самостоятельно, но потом у меня было так много проблем с Mongoose и его ограничительным характером, что я решил попробовать использовать для этого встроенный драйвер MongoDB.Я действительно не хочу начинать с нуля, так как считаю, что это должно быть довольно просто.У меня возникли трудности с тем, что Mongoose "магически" знает, как использовать соединение с БД, открытое в app.js, но когда я заменяю MongoClient на mongoose, вызовы MongoClient, которые я выполняю из service.ts, похоже, не имеютлюбой признак того, что постоянное соединение уже открыто и что-то не получается.Вот мой код:

app.js:

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var cors = require('cors');
var app = express();

const MongoClient = require(`mongodb`).MongoClient;
const mongodb_uri = 'mongodb://127.0.0.1:27017/test';
var mongoose = require('mongoose');
var bluebird = require('bluebird');

var api = require('./routes/api.route')

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/api', api);

mongoose.Promise = bluebird
MongoClient.Promise = bluebird

// Open MongoDB Connection

//old from tutorial - works
//mongoose.connect('mongodb://127.0.0.1:27017/test', { useNewUrlParser: true, autoIndex: false })
//.then(()=> { console.log(`Succesfully connected to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`)})
//.catch(()=> { console.log(`Error connecting to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`)})

//this opens a connection, but the other modules can't seem to "see" it
MongoClient.connect(mongodb_uri, { useNewUrlParser: true })
.then(()=> { console.log(`Succesfully connected to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`)})
.catch((e)=> { console.log(`Error connecting to the MongoDb database at URL: mongodb://127.0.0.1:27017/test: ` + e)})

//I figured I could make this a variable and maybe the other modules would see it:
//const mongoConn = MongoClient.connect(mongodb_uri, { useNewUrlParser: true })
//.then(()=> { console.log(`Succesfully connected to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`)})
//.catch((e)=> { console.log(`Error connecting to the MongoDb database at URL: mongodb://127.0.0.1:27017/test: ` + e)})

//This was another method I was given, but it doesn't work either:
//let testConnection; // allows us to reuse the database connection once it is opened
/*const open_test_connection = async () => {
  try {
    client = await MongoClient.connect(mongodb_uri, { useNewUrlParser : true });
    console.log(`Succesfully connected to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`);
  } catch (err) {
    console.log(`Error connecting to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`); 
    throw new Error(err); 
  }
  testConnection = client.db('test');
};*/

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
  next();
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

//this was me trying to add "mongoConn" to the exports to see if that might work
module.exports = app, mongoConn;

Это фрагмент кода из модуля service.ts, который выполняет реальную работу (я могу предоставить controller.ts и другие,но они почти такие же, как урок, и этот пост уже очень длинный):

exports.updateTestData = async function(update){
    var id = update._id

    // Check the existence of the query parameters, If they don't exist then assign a default value
    var dbName = update.dbName ? update.dbName : 'test'
    var collection = update.collection ? update.collection : 'testing'; 

    //old Mongoose way
    //const Test = mongoose.model(dbName, TestSchema, collection);

    try{
        //For some reason the tutorial wanted to find the doc before updating it
        //I plan to take this out
        //For now this is what I am testing with - note the use of "mongoConn" which I expect
        //to be available from app.js
        //Find the existing Test object by the Id
        var existingTestData = await mongoConn.collection(collection).findById(id);
        console.log(existingTestData)
    }catch(e){
        throw Error("Error occurred while finding the Test document - " + e)
    }

    // If no existing Test object exists return false
    if(!existingTestData){
        return false;
    }

    console.log("Existing document is " + existingTestData)

    //Old code from tutorial
    //existingTestData.title = update.title
    //existingTestData.description = update.description
    //existingTestData.status = update.status

    //I replaced it with this because I don't want static keys
    existingTestData = new Test(JSON.parse(JSON.stringify(update)));


    console.log("New data is " + existingTestData)

    try{
        //old tutorial method - save is being deprecated and I don't want findById anymore
        //so I am going to use findByIdAndUpdate instead - not again the "mongoConn" from app.js
        //var savedOutput = await existingTestData.save()
        var savedOutput = await mongoConn.findByIdAndUpdate(id, existingTestData, {new:true})
        return savedOutput;
    }catch(e){
        throw Error("An error occurred while updating the Test document - " + e);
    }
}

Я чувствую, что мне не хватает того, что нужно MongoClient, в чем нет необходимости при использовании Mongoose.Я искал несколько дней и не могу понять, что я делаю не так.Любая помощь будет принята с благодарностью.

...