中间件模式算是最 Node 风格的 Web 应用构建方式,但是我在使用 express 的中间件的过程中,发现似乎缺少管理中间件之间的依赖的功能,找了一些库,但是感觉这个简单的问题被描述得复杂化了,于是我自己写了一个简单的依赖注入工具,总计才 12 行。
源码贴在这里:
_ = require 'underscore'
async = require 'async'
module.exports = (req, res, next) ->
req.inject = (dependency, callback) ->
if req.injected
dependency = _.reject dependency, (item) ->
return item in req.injected
async.eachSeries dependency, (item, callback) ->
req.injected = [] unless req.injected
req.injected.push item
item req, res, callback
, callback
next()
也发在了 npm 上面: https://www.npmjs.org/package/middleware-injector 当然,这是花了半个小时搞出来的,肯定不是最好的解决方案,欢迎提供更好的解决方案。
下面是一个典型的应用场景:
parseToken = (req, res, next) ->
req.token = req.cookies.token
next()
accountInfo = (req, res, next) ->
req.inject [parseToken], ->
mAccount.authenticate req.token, (account) ->
req.account = account
next()
errorHandling = (req, res, next) ->
res.error = (name, param) ->
param = _.extend param, error: name
res.json 400, param
next()
requestAuthenticate = (req, res, next) ->
req.inject [accountInfo, errorHandling], ->
if req.account
next()
else
if req.method == 'GET'
res.redirect '/account/login/'
else
res.error 'auth_failed'
10 回复
@rekey 我是打算在应用层重度使用中间件的,比如我有几个和 book 有关的 API, 我需要根据客户端提供 book_id, 去数据库查到相应的记录再操作,这个过程我会用中间件来完成。但是并非所有请求都跟 book 有关,如此一来,中间件之间的依赖关系就很复杂了。