Home > Back-end >  Using the same module for two endpoints
Using the same module for two endpoints

Time:01-27

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.

CodePudding user response:

OK, I'm guessing that you want a separate instance of your Merkle class for each.

Modules are cached so they only run their own initialization just once. So, the way you had it before, you had one router and one instance of your Merkle object. To have separate instances you move the code into a function so it can be called as many times as you want and will create a new Merkle object each time. Here's one way to do that:

const Merkle = require('../modules/merkle');
const express = require('express');

module.exports = function() {
    const router = express.Router();
    const 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())
    })
    return router;
}

Then, use it like this:

const whiteListFn = require('./routes/whitelist');

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

CodePudding user response:

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())
  •  Tags:  
  • Related