Dave
Dave

Reputation: 567

Is there a way to avoid multiple next() in express middleware

This is how I've designed my route and I'm not really happy with it. I'd rather be able to break down each hasValid into its own middleware, but I don't see how that would work since it wouldn't stop execution.

const secretSender = async (req, res, next) => {
  if (!hasValidA(req)) {
    return next()
  }

  if (!hasValidB(req)) {
    return next()
  }

  if (!hasValidC(req)) {
    return next()
  }

  if (!hasValidD(req)) {
    return next()
  }

  res.send('something secret')
}

router.use(secretSender)
router.get('*', (req, res) => {
  res.send('something public')
})

It also doesn't really make sense to make the default route "something secret" and have "something public" be the middleware since "something public" is the default behavior.

Upvotes: 0

Views: 716

Answers (1)

IronGeek
IronGeek

Reputation: 4873

Here's one way to break down each hasValid into its own middleware. Each middleware will short-circuit the execution if the outcome is valid:

const validA = async (req, res, next) => {
  if (hasValidA(req)) {
    res.send('something secret') 
  } else {
    next()
  }
}

const validB = async (req, res, next) => {
  if (hasValidB(req)) {
    res.send('something secret')
  } else {
    next()
  }
}

const validC = async (req, res, next) => {
  if (hasValidC(req)) {
    res.send('something secret') 
  } else {
    next()
  }
}

const validD = async (req, res, next) => {
  if (hasValidD(req)) {
    res.send('something secret')
  } else {
    next()
  }
}

router.use(validA, validB, validC, validD)
router.get('*', (req, res) => {
  res.send('something public')
})

Update

To achieve somewhat similiar result with OP's code, but only with single next():

const secretSender = async (req, res, next) => {
  if (hasValidA(req) && hasValidB(req) && hasValidC(req) && hasValidD(req)) {
    res.send('something secret')
  } else {
    next()
  }
}

router.use(secretSender)
router.get('*', (req, res) => {
  res.send('something public')
})

Upvotes: 2

Related Questions