在PHP社区中,FIG(框架互操作组)采用了PSR-7(HTTP消息接口),中间件正受到越来越多的关注。对于将来的框架选择,我研究了Node.js和Go中间件以及PHP。
背景
对微服务的兴趣与日俱增
据推测,在采用中间件的项目兴起之后,对微服务的兴趣正在增加。 Lumen是一种用于开发微服务的解决方案,它声称比用PHP编写的竞争微框架要快。
PHP Framework速度比较是一个PHP Framework Benchmark项目,
有关不同语言的框架的速度比较,请参见(Web框架基准)。
微服务先决条件
Martin Fowler在其有关微服务先决条件的文章中引用了以下内容:
快速配置
基本监控
快速部署应用程序
微服务的权衡
Martin Fowler在微服务折衷中的文章中写道,优点是"强大的模块边界","单独部署","技术多样性"和缺点。它列出了"分布式","最终完整性"和"操作复杂性。"
微服务案例研究
从Go的单片Ruby到微服务将很有帮助。通过将pdf生成切换为并发,速度提高了12倍,内存消耗减少了30%。通过切换报告卡的计算过程,速度提高了10倍。
据说采用Go微服务的原因是易于部署,并且只花了2个小时就安装了AWS CodeDeploy。
示例也发布在与微服务相关的材料摘要中。
中间件用例
StackPHP开发人员Igor在" HttpKernel中间件"中列出了以下功能,作为很好的用例:
认证方式
调试工具栏
注入的路由-例如,管理面板。
签名的cookie
资产管理
强制SSL
错误处理
会议
路由器
路由器(路由)可以作为一个具体示例,其中中间件的优点易于理解。如果使用中间件,则可以根据每个项目或服务的优先级来切换路由器。例如,您可以专注于速度并坚持简单的模式,或者接受较慢的速度而不是处理复杂的模式。
中间件约束
烟囱和滤清器链的极限
检查案例时,通常会使用按注册顺序执行的堆栈或过滤器链(责任链)。
如果框架或应用程序使用允许您指定事件和优先级的系统(例如事件总线和事件分派器)来解决更复杂的问题,则可用性很方便。
统一API很困难
如果
API是统一的,则可以由各种项目共享,但是很难有一个统一的API可以被任何项目采用,例如Expressive和StackPHP之间的区别。
Ruby Rack社区一直在讨论the_metal和Rack-Next的下一个主要版本,但似乎已经失控了。
从现在开始,PSR-7将会流行
对于PHP,PSR-7(中间件的前提)在2015年才被采用,您必须至少等待几年才能确定其是否流行。采用PSR-7的新项目可能不会出现,现有社区很大的项目可能看不到迁移到PSR-7的好处,或者PSR-7可能不会普及。
中间件分类
独立组件
与插件和扩展名互换使用。不同之处在于,HTTP是中心关注的问题,并且可以在多个框架和应用程序中使用。
我们致力于注册和执行中间件,并且往往没有诸如DI容器和路由器之类的最低功能。在某些情况下,曾经是框架功能的一部分,已经成为一个复杂的独立项目。
node.js包含Koa和connect。 PHP包括用于PSR-7的Relay和Zend Stratigility。评估和使用Symfony 2的HttpKernel作为中间件的另一个计划是StackPHP。 Golang包括Negroni和Alice。
PHP(兼容PSR-7)
Zend Stratigility /富有表现力 h5>
对于Zend Stratigility / Expressive,采用与Express相同的参数。
$app->pipe('/foo', function ($req, $res, $next) {
return $res->end('Foo');
});
中继 h5>
function (
Request $request, // the request
Response $response, // the response
callable $next // the next middleware
)
PHP(不支持PSR-7)
StackPHP h5>
对于StackPHP,使用Stack / Builder push方法注册一个实现Symfony的HttpKernelInterface的对象。 HttpKernelInterface的handle方法将Request作为参数,将Response作为返回值。
function handle(Request $request)
$stack = (new Stack\Builder())
->push('Stack\Session')
node.js
考阿 h5>
function *(next)
go
内格罗尼 h5>
Negroni由与Martini相同的开发人员开发,允许您仅注册特定路线的中间件。
router := mux.NewRouter()
adminRoutes := mux.NewRouter()
// add admin routes here
// Create a new negroni for the admin middleware
router.Handle("/admin", negroni.New(
Middleware1,
Middleware2,
negroni.Wrap(adminRoutes),
))
爱丽丝 h5>
通过Alice,可以轻松连接多个中间件。
func (h http.Handler) http.Handler
alice.New(Middleware1, Middleware2, Middleware3).Then(App)
,扩展框架的主要手段
与插件和扩展名互换使用。
node.js包括Express 4中间件。在PHP中,PSR-7有Slim 3。对于围棋,马提尼就是其中之一。
PHP(兼容PSR-7)
苗条3 h5>
function ($request, $response, $next)
Node.js
快车4 h5>
function (req, res, next)
Go
马提尼 h5>
据说马提尼酒是受Express和Sinatra的启发。
m.Use(func(res http.ResponseWriter, req *http.Request) {
})
m.Use(func(c martini.Context, log *log.Logger) {
})
m.Handlers(
Middleware1,
Middleware2,
Middleware3,
)
,扩展框架的辅助手段
可以使用其他扩展,例如插件和扩展。自2000年代以来就存在的框架具有过滤器方法,例如before和after。
PHP(不支持PSR-7)
Laravel h5>
对于
Laravel,除了请求和