Zastanawiam się, jaki jest najlepszym sposobem na ponowne wykorzystanie połączeń DB w moim przypadku, gdy jest to połączenie couchbase w Nodejs, a także Express. Dla części ekspresowej stworzyłem w ten sposób oprogramowanie pośrednie

var couchbase = require('couchbase')
var config = require('../config/config')

module.exports = (req,res,next)=>{
  var cluster = new couchbase.Cluster(config.cluster)
  cluster.authenticate(config.userid, config.password)
  let bucket = cluster.openBucket(config.bucket);
  bucket.manager().createPrimaryIndex(function() {});
  req.bucket = bucket;
  req.N1qlQuery = couchbase.N1qlQuery;
  next();
}

Który działa dobrze w aplikacji Express, ponieważ mówię

const dbSessionMiddleware = require('../middleware/couch')
app.use(dbSessionMiddleware) 

Który pozwala mi uzyskać dostęp do niej przez req.Bucket. Moim problemem jest to, że mam kontrolery w mojej aplikacji, która w przypadku może zadzwonić do funkcji pomocnika i mogą nazwać inną funkcję, aby uzyskać dane z powrotem. Chcę uniknąć przekazywania obiektu żądania w dół 5 poziomów lub tak, aby korzystać z oprogramowania pośredniego. Czy jest lepszy sposób, w jaki sposób mogę narysować połączenie / wiadro do normalnych funkcji?

2
MisterniceGuy 25 luty 2019, 00:14

2 odpowiedzi

Najlepsza odpowiedź

Czy próbowałeś wybrać swój kod init z funkcji oprogramowania pośredniego? Dokumentacja CouchBase nie pokazuje go w ten sposób. Chociaż przykład jest w wanilii węzła. Umieszczając go w funkcji oprogramowania pośredniego, zostaniesz ponownie podłączony do bazy danych za każdym razem, gdy serwer odbiera żądanie.

Połącz się z moim serwerem Mongo na najwyższym poziomie APP.js, który umożliwia utrzymanie połączenia. Wtedy mogę po prostu zaimportować Mongoose Reference, którego potrzebuję w moich modelach i kontrolerowi, aby zarysować, jak pobrać pewne dane, a następnie połączyć metodę kontrolera w odpowiednim punkcie końcowej trasy.

edytowane, aby pokazać przykład przypisywania wiadra jako pola klasy kontrolera

w twoim app.js

const couchbase = require("couchbase");
const config = require("../config/config");

// ...app.js

const CouchController = require("../controllers/CouchController")(couchbase, config);

// app.js...

w kontrolera

class CouchController {

  constructor(couchbase, config) {
    // You may either pass couchbase and config as params, or import directly into the controller
    this.cluster = new couchbase.Cluster(config.cluster);
    this.cluster.authenticate(config.userid, config.password);
    this.bucket = cluster.openBucket(config.bucket);
    this.N1qlQuery = couchbase.N1qlQuery;
  }

  doSomeQuery(queryString, callback) {

    // Use your query however its meant to be used. I'm not familiar with couchbase queries.
    this.bucket.manager().createPrimaryIndex(function() {

      this.bucket.query(
        this.N1qlQuery.fromString("SELECT * FROM bucketname WHERE $1 in interests LIMIT 1"),
        [queryString],
        callback(err, result)
      )

    });
  }

}

, a następnie wywołaj metodę sterownika z wewnątrz trasy

router.get("/", function(req, res, next) {

  let searchParam = req.query.someParam;

  CouchController.doSomeQuery(searchParam)
    .then(result => {
      res.json(result);
    });

});
3
Drowsy 25 luty 2019, 01:09

Możesz utworzyć wyspecjalizowany moduł (np db.js), gdzie zaimplementowałbyś singleton na pulę połączeń.

// pseudo-code
export const getDb = () => {
  let db

  if (!db) {
    const connection = createConnectionPool()
    db = connection.db
  }

  return db
}

Ta funkcja może być importowana na podstawie oprogramowania pośredniego i na innych częściach kodu.

1
Joilson Cisne 24 luty 2019, 21:26