Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Early return / short circuit pattern #480

Open
cjroebuck opened this issue May 16, 2023 · 2 comments
Open

Early return / short circuit pattern #480

cjroebuck opened this issue May 16, 2023 · 2 comments

Comments

@cjroebuck
Copy link

cjroebuck commented May 16, 2023

Hey , any recommendations on how to do the following pattern in a route handler, hopefully the pseudo code makes sense:

(req, res, next) => {
  loadUser(req)
    .andThen(validateUser)
    .andThen(lookupCache) // <-- if lookupCache actually finds a result in the cache, we want to skip straight to the match() and return a response
    .andThen(validateOptions)
    .andThen(doSomethingExpensive)
    .andThen(putInCache)
    .match(result=>{
      res.send(200,{status:"ok",result})
    },err=>{
      res.send(400,{status:"notok",error:err.message});
    })
}

Basically.. I want to short circuit the pipeline if lookupCache finds a result, but continue otherwise.

The only way I can see to do it without breaking this out into two pipelines.. is to return a special error and handle that in the error case..

Otherwise this is kinda what i'm doing now.. but it feels ugly somehow..

(req, res, next) => {
  loadUser(req)
    .andThen(validateUser)
    .andThen(lookupCache)
    .match(result =>{
      if(result.isCacheHit){
        res.send(200,{status:"ok",result});
        return next();
      }      
      validateOptions(result)
        .andThen(doSomethingExpensive)
        .andThen(putInCache)
        .match(result=>{
          res.send(200,{status:"ok",result})
        },err=>{
          res.send(400,{status:"notok",error:err.message});
        })
    },err=>{
      res.send(400,{status:"notok",error:err.message})
    }) 
}

it feels ugly because i'm doing the res.send part in multiple places, when I just want to handle it in one .match call..

@paduc
Copy link
Contributor

paduc commented May 16, 2023

Hello @cjroebuck

This is how I proceed

(req, res, next) => {
  loadUser(req)
    .andThen(validateUser)
    .andThen(lookupCache)
    .andThen((cache) => {
      if(cache) return Ok(cache)

      return validateOptions()
        .andThen(doSomethingExpensive)
        .andThen(putInCache)
    })
    .match(result=>{
      res.send(200,{status:"ok",result})
    },err=>{
      res.send(400,{status:"notok",error:err.message});
    })
}

@cjroebuck
Copy link
Author

I see.. thank you @paduc, that is a bit nicer!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants