带中间件的api调用链|php与nodejs的异同
php几年前已经采用nodejs管理应用依赖包的方法(npm/borwser),产生了composer;现在,api接口开放时代,php的微型框架slim为api而生,它集成psr/全名空间/中间件的方式,这种由python django(https://docs.djangoproject.com/en/1.6/topics/http/middleware/)流行而来的处理方式已经被其它框架所接受,比如nodejs的koa。
现在slim已经进行到3.0,每个版本的更新都很激进,几乎面目全非。
slim3中关于中间件的说明是这样的:
http://www.slimframework.com/docs/concepts/middleware.html
可以看出,请求通过入口,经层层的中间处理,比如过滤、认证、加载数据库、加载缓存。。。最后到达app核心层,然后response又经原路返回,最后输出。
每个middleware都是一个匿名函数,函数处理完毕,最后返回一个对下一中间件的调用;如果没有调用,那么中断对其余中间的处理,直接到达核心的app,输出结果。
<?php
class ExampleMiddleware
{
/**
* Example middleware invokable class
*
* @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request
* @param \Psr\Http\Message\ResponseInterface $response PSR7 response
* @param callable $next Next middleware
*
* @return \Psr\Http\Message\ResponseInterface
*/
public function __invoke($request, $response, $next)
{
$response->getBody()->write('BEFORE');
$response = $next($request, $response);
$response->getBody()->write('AFTER');return $response;
}
}
nodejs中,koa框架也是这个原理:
http://koa.rednode.cn/#introduction
不同的是,nodejs通过es6的generator关键字yield来传递到下一中间件的:
var koa = require('koa');
var app = koa();// x-response-time
app.use(function *(next){
var start = new Date;
yield next;
var ms = new Date - start;
this.set('X-Response-Time', ms + 'ms');
});// logger
app.use(function *(next){
var start = new Date;
yield next;
var ms = new Date - start;
console.log('%s %s - %s', this.method, this.url, ms);
});// response
app.use(function *(){
this.body = 'Hello World';
});app.listen(3000);
.middleware1 {
// (1) do some stuff
.middleware2 {
// (2) do some other stuff
.middleware3 {
// (3) NO next yield !
// this.body = 'hello world'
}
// (4) do some other stuff later
}
// (5) do some stuff lastest and return
}
-- end --