在本文中,我将讨论Midmare的特性和功能,并分享创建自己的库的经验。
背景
我正在使用的产品目前正在迁移过程中。直到结束,我们在两个平台上并行存在,并摆脱了传统。我正在为一个新平台做一个Web应用程序后端。有些流程必须与其他团队不断统一。
考虑到这些功能,有必要找到一种灵活且通用的解决方案来重写现有后端。该解决方案是Midmare库。
介绍性任务
我要完成一个任务,以便该库可以与TypeScript和JavaScript一起使用。同时,该团队旨在将代码从TS完全重写为JS,以加快开发速度。
JS没有类型化,因此使用它的速度更快,尽管不稳定。我们愿意承担计划通过编写足够的测试来保护自己的风险。
起初,我花了一个半星期的时间来思考这个概念,经历了不同的选择。在我想到使用功能性方法很酷的想法之前,可以在任何执行链中插入任何链接而不会产生任何后果。
我想到了使用中间件的想法
即,使一系列中间处理功能相互执行,并对彼此的错误(错误,问题,数据更改等)做出反应。
因此,我得到了一堆中间件,其原理与Koa类似。这种相似性确保了库的其余部分易于使用。但是在Midmare中,方法要少得多,只有4种。Midmare库本身是简约的。
开始工作
在安装Midmare之前,您需要下载并安装Node.js版本10或更高版本。创建新项目时,还需要先使用npm init命令创建package.json 。
通过npm install midmare命令完成Midmare的安装。
下面是示例应用程序初始化。使用
路由器在Midmare上的常规应用程序初始化
(路由器级中间件)
Midmare功能
首先,我们谈论的是令人印象深刻的代码分解功能。中间功能(中间件)可能对彼此一无所知。他们只是获取数据,对其进行处理并进一步发布。
如果您需要对不同的API(源和目标)使用相同的路由系统,则Midmare库是理想的选择。也就是说,当您需要创建某个通用处理节点时。但是您也可以创建更简单的应用程序。
以下是一些突出Midmare功能的示例。
使用中间函数捕获错误。他也是代码分解的一个示例
一个简单的中间函数,在路由不匹配的情况下关闭HTTP会话
处理命令的示例,在这种情况下,将数据发送到Redis
小型库的工作量很小,但是它不会以任何方式限制您可用的选项。在Midmare中,您几乎可以连接任何东西-无需困惑如何构建体系结构。
关键优势
该库的主要优点是与任何层(HTTP,WS等)完全隔离。如果Koa是为HTTP服务器设计的,则Midmare在这方面不会产生限制。
您甚至可以编写终端实用程序。使用Midmare,这很方便,因为我们可以在中使用参数
path
。如下例所示:
使用Midmare,您可以返回到同一HTTP服务器。连接起来并不难。已经有一个现成的HTTP路由器。
这样,您还可以安全地连接WebSocket。您只需要初始化WebSockets客户端本身。然后由最简单的路由决定。
HTTP和WebSocket与Midmare结合的示例
这种多功能性消除了在一个程序中以不同的方式解决同一问题的思考。
实际上,很难列举所有实现的可能性,因为任何想法都可以不受限制地应用于库。
我还没有看到这种格式的现成库
也就是说,这是一个完整的模拟:没有低级绑定,无论是WebSockets,HTTP还是更广泛的网络通信或软件都可以在OS本身中工作。
Midmare可以同时完成所有任务,而且实际上可以进行5-6行调整。
其背后的想法非常简单-使用next / send方法调用来构建函数执行链。如果不需要进一步调用,该程序将停止。加上路由,减去HTTP-我们有了Midmare。
为什么要使用这个库?
您可以随时编写自己的解决方案。当然,在这种情况下,您的分解或代码本身可能很la脚(例如,您可能无法在链中的各个步骤之间进行调整)。如果存在许多这样的缺陷,那么用手工编写的程序可能在一两年之内就会陷入困境。Midmare避免了这种情况。
此外,程序员领域中的过滤器太多。有人想用TypeScript编写,有人想用JS。我一直在寻找一种解决方案来捕获这两种选择。
现在,我尝试积极地测试和完善Midmare
,而小型图书馆的一大优点是其创建者积极地支持它。
我每天都要测试我的图书馆,并因此迅速找到陷阱或缺陷。使用小型图书馆,任何问题都可以立即得到解决。
循环调用是已解决的第一个问题
让我们看下面的示例:
假设我们需要在.process('/ message')步骤中添加一个'/ send'调用,但是.process('/ send')已包含一个'/ message'调用。然后,步骤2将调用步骤1。同时,在步骤1中,每次都会触发对步骤2的调用-依次类推。
在创建库时,您需要抓住这些问题,向用户展示它们,并解释其中的问题。
在这种情况下,我们将得到“超出最大调用堆栈大小”错误,并且JS将响应对同一函数的多个递归调用而崩溃。
此库中解决此问题的方法是:将路径历史记录保留在一个上下文中。也就是说,每次对ctx.send或app.send的调用都有自己的调用历史记录。
由于Midmare在这一点上有一个句柄,因此如果在循环中调用该库,则会引发错误。
可能存在需要通电话的情况。例如,两个中间函数以不同的方式处理相同的数据,因为有可能脱离循环。也就是说,当其中一个函数包含if-else时,它将在else中工作并且忽略循环调用。
万一实现需要循环,Midmare可以选择通过`ignoreCycleError:true`设置要忽略的错误。
图书馆正在等待社区
原则上,向这种纯库添加任何内容都是没有意义的。添加连接插件的功能会很好,但是使用中间件可以解决此问题,而无需新功能。
如果在特定情况下缺少某些处理,则可以将其自己添加到有条件的4行中。与具有关闭HTTP会话功能的示例一样:
所有其他处理都可以移到单独的存储库中。或将路由器分发到存储库。一切都将以相同的方式连接和处理。
图书馆目前真正做得好的地方是一个可以从图书馆构建自己的工具的社区。因此,我邀请社区为图书馆的发展做出贡献。加入并测试。
作者:Ivan Petushinsky,高级Node.js开发人员