'Using the same module for two endpoints

I'm working on an express js server for some whitelisting. I need to make two whitelists, but I don't want to just make two files for them.

var whitelistOneRouter = require('./routes/whitelist')
var whitelistTwoRouter = require('./routes/whitelist')

app.use("/whitelists/whitelistOneRouter", whitelistOneRouter)
app.use("/whitelists/whitelistTwoRouter", whitelistTwoRouter)

whitelist.js

var router = express.Router();
var Merkle = require('../modules/merkle')

var merkleOne = new Merkle([])

router.get('/', function (req, res, next) {
    var address = req.body.address
    var proof = merkleOne.getProof(address)
    res.send(proof)
})
router.get('/root', function (req, res, next) {
    res.send(merkleOne.getRoot())
})
router.post('/new', function (req, res, next) {
    var whitelist = req.body.whitelist
    merkleOne.setNewWhitelist(whitelist)
    res.send(merkleOne.getRoot())
})

module.exports = router;

When I try to interact with one endpoint, it changes the other and vice versa. Does anyone know a better way to do this? I don't want to make another file that's the same code.



Solution 1:[1]

Modules in Node.js are essentially singletons.

Where ever you require the path that ./routes/whitelist resolves to, it will export the same merkleOne and router as they are defined in the modules outermost scope.

If you want to share the code, then exporting a factory function is one way to achieve separate instances

function newMerkleRouter(){
  var merkleOne = new Merkle([])
  var router = express.Router();
  router.get('/', function (req, res, next) {
    var address = req.body.address
    var proof = merkleOne.getProof(address)
    res.send(proof)
  })
  router.get('/root', function (req, res, next) {
    res.send(merkleOne.getRoot())
  })
  router.post('/new', function (req, res, next) {
    var whitelist = req.body.whitelist
    merkleOne.setNewWhitelist(whitelist)
    res.send(merkleOne.getRoot())
  })
  return router
}
app.use("/whitelists/whitelistOneRouter", newMerkleRouter())
app.use("/whitelists/whitelistTwoRouter", newMerkleRouter())

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Matt