自己写了一个中间件依赖注入工具 middleware-injector
发布于 10 年前 作者 jysperm 4548 次浏览 最后一次编辑是 8 年前

中间件模式算是最 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 回复

中间件要安排好流程顺序就行,过多的依赖会造成维护困难,这么注入不还是链式执行。

你这个模块会不会遇到跟 npm 一样的重复依赖问题?

比如 a 和 b 都依赖 c,那么我在 a 和 b 的声明中都写了 c,这样 c 会不会被执行两次?

不会,重复的依赖只会执行一次,这也是这个工具的意义。

我是打算在应用层重度使用中间件模式的,所以不可避免地会遇到依赖管理的问题,这个工具会保证对于每个请求只会执行需要用到的中间件,并且每个中间件只执行一次。

怎么着都不如直接在app.js里先后顺序的定义来的一目了然。。。你真的需要那么多中间件么?

先后顺序其实就行了,不过这个di的想法有点意思

di 还是使用强大的 bearcat

@rekey 我是打算在应用层重度使用中间件的,比如我有几个和 book 有关的 API, 我需要根据客户端提供 book_id, 去数据库查到相应的记录再操作,这个过程我会用中间件来完成。但是并非所有请求都跟 book 有关,如此一来,中间件之间的依赖关系就很复杂了。

如果是这样,那么你应该要有更好的设计,而不是依赖于工具去解决。

你的 book 是不是就几个 url 用到?

回到顶部