Search code examples
node.jsmongodbmonk

How to implement different middlewares for different monk's Manager instance?


I'm using monk (https://automattic.github.io/monk/) in order to do mongodb data manipulation.

Monk has a middleware mechanism, and we can simply invoke addMiddleware to add as many middleware as needed (https://automattic.github.io/monk/docs/middlewares.html)

It works well until I create two manager (https://automattic.github.io/monk/docs/manager/) instance. The middlewares of the two manager seems to polute each other.

So, I create a simple test in order to make sure the hypothesis. Here is the test:

  let db = monk('mongodb://localhost/test')
  let softDb = monk('mongodb://localhost/other')
  console.error(db._collectionOptions.middlewares === softDb._collectionOptions.middlewares)

And as my prior hypothesis, it yield true. Eventhough db and softDb are different objects, they seems to share the same _collectionOptions.middlewares. Probably monk's developer implement singleton pattern.

My question is: how could I make this softDb and db have different set of middlewares?

Thanks in advance.


Solution

  • I find a workaround. This is not an officially approved solution and I'm still seeking for a better solution. So, if any of you find a better solution, I'll approve your answer.

    Since both softDb and db share the same set of middleware, then I deep-clone and re-assign both db._collectionOptions.middlewares. For deep-cloning purpose, I use this package: https://www.npmjs.com/package/clone.

    The solution looks as follow:

    let clone = require('clone')
    
    let db = monk('mongodb://localhost/test')
    db._collectionOptions.middlewares = clone(db._collectionOptions.middlewares)
    
    let softDb = monk('mongodb://localhost/other')
    softDb._collectionOptions.middlewares = clone(softDb._collectionOptions.middlewares)
    
    // Here I can add different set of middlewares to db and softDb
    // The middlewares of both manager will be independent to each other
    
    console.error(db._collectionOptions.middlewares === softDb._collectionOptions.middlewares)
    // Now, this will yield `false`
    

    It is important to note that you have to copy the middlewares immediately after creating a manager instance.

    I'm aware that some people might hate this solution. So, rather than down-voting this answer, please provide a better solution instead.