停止KOA中的中间件管道执行

时间:2015-06-10 10:41:36

标签: node.js generator middleware koa

我想问一下是否有办法停止在KOA中执行中间件管道?

在下面的示例中,我有一个中间件可以某种方式验证某些东西。如何在验证失败时重新编写中间件代码以停止执行?

var koa = require('koa');
var router = require('koa-router')();
var app = koa();

app.use(router.routes());

// middleware
app.use(function *(next){
  var valid = false;
  if (!valid){
    console.log('entered validation')
    this.body = "error"
    return this.body; // how to stop the execution in here
  }
});

// route
router.get('/', function *(next){
  yield next;
  this.body = "should not enter here";
});


app.listen(3000);

我实际上可以改变我的路线:

router.get('/', function *(next){
  yield next;
  if(this.body !== "error")
    this.body = "should not enter here";
});

但是有更好的方法吗?或者我错过了什么?

  

这只是一个例子,实际上我的中间件可能会放置一个属性   在体内(this.body.hasErrors = true),路线将从中读取   这一点。

同样,我怎么能停止在我的中间件中执行,以便我的路由不会被执行?在快递中,我认为你可以做出回应。但是(虽然不确定)。

1 个答案:

答案 0 :(得分:3)

中间件按照您将其添加到应用程序的顺序执行 您可以选择屈服于下游中间件或提前发送响应(错误等)。 因此,停止中间件流程的关键是不要屈服。

app.use(function *(next){
  // yield to downstream middleware if desired
  if(doValidation(this)){
    yield next;
  }
  // or respond in this middleware 
  else{
    this.throw(403, 'Validation Error');
  }
});

app.use(function *(next){
  // this is added second so it is downstream to the first generator function
  // and can only reached if upstream middleware yields      
  this.body = 'Made it to the downstream middleware'
});

为清晰起见编辑:

下面我修改了您的原始示例,使其按照我认为您打算的方式运行。

var koa = require('koa');
var router = require('koa-router')();
var app = koa();

// move route handlers below middleware
//app.use(router.routes());

// middleware
app.use(function *(next){
  var valid = false;
  if (!valid){
    console.log('entered validation')
    this.body = "error"
    // return this.body; // how to stop the execution in here
  }
  else{
    yield next;
  }
});

// route
router.get('/', function *(next){
  // based on your example I don't think you want to yield here
  // as this seems to be a returning middleware
  // yield next;
  this.body = "should not enter here";
});

// add routes here
app.use(router.routes());

app.listen(3000);