gpt4 book ai didi

javascript - 具有函数式编程(纯路由)的 Express.js 服务器

转载 作者:搜寻专家 更新时间:2023-10-31 23:03:47 24 4
gpt4 key购买 nike

我的目标是能够为 Express.js 服务器编写纯路由。这可能吗?

为了访问数据库和我知道的东西,我可以使用神奇的 Future monad 来保持纯净,但是路由渲染本身呢?

我发现的最大困难之一是一条路线可能以多种不同的方式结束,例如:

  • 重定向
  • 模板渲染
  • 错误返回
  • 返回json
  • 文件返回

使用 Future monad,我可以处理错误和成功案例,但之后的成功案例就没有更多的粒度了。

有没有办法为 Express.js 编写纯粹且完全可测试的路由?

最佳答案

简短回答:不 - 这是不可能的。

解释:在函数式编程的上下文中,我们有一个数据流 - 程序获取一些输入数据,对其进行转换并返回输出数据

对于服务器,我们有两个数据流。首先是当您启动服务器时。在此流程中,您可能希望从外部世界读取配置文件或命令行参数,以获取端口、主机、数据库字符串等内容。这是副作用,因此我们通常将其放在 Future 中。例子,

readJson(process.argv[2])    // Read configuration file
.chain(app) // Get app instance (routes, middlewares, etc.)
.chain(start) // Start server
.run().promise()
.then((server) => info(`Server running at: ${server.info.uri}`))
.catch(error);

这是包含所有副作用(读取配置)的典型 index.js 文件。现在让我们转向第二个数据流。

这个数据流有点难以想象。第一个数据流的输出/副作用是服务器在某个端口上监听外部连接。 现在想象一下,到达此服务器的每个请求本身都是一个独立的数据流。

就像 index.js 是用来处理所有副作用的文件一样,您的路由文件或路由处理函数是用来处理副作用的,即结果请求应该在这个路由处理程序。通常,接近纯功能的路线如下所示:

function handler(request, reply) {

compose(serveFile(reply), fileToServe)(request)
.orElse((err) => err.code === 'ENOENT' ? reply404(reply) : reply500(reply))
.run(); // .run() is the side effect
}

return {
method: 'GET',
path: '/employer/{files*}',
handler
};

在上面的片段中,一切都是纯粹的。唯一不纯的东西是 .run() 方法(我正在使用 Hapi.js 和 Folktale.js Task)。

与 Angular 或 React 等前端框架的想法相同。这些框架中的组件应包含所有效果/杂质。这些组件就像您的路由处理程序一样是应该发生副作用的端点。您的模型/服务应该没有杂质。

话虽如此,如果你仍然想让你的路线完全纯净,那就有希望了。您本质上想要做的是 - 更高级别的抽象:

  1. 如果 Express.js 是一个框架,那么您应该在其之上构建自己的抽象。
  2. 您通常会为所有路由编写自己的通用路由处理程序,并公开自己的 API 来注册路由。
  3. 然后您的路由处理程序将返回 future/task/observable 或任何其他包含所有等待释放的副作用的 monad。
  4. 然后您的抽象路由处理程序将简单地调用 .fork().run()
  5. 这意味着当您对路由处理程序进行单元测试时,不会发生任何副作用。它们只是简单地包装在一些 Async Monad 中。

如前所述,对于前端框架,您的 UI 组件会有副作用。但是有一些新的框架超越了这种抽象。 Cycle.js 是我所知道的一个框架。它应用了比 Angular 或 React 更高级别的抽象。所有的副作用都被关在 observable 中,然后被分派(dispatch)到一个框架并执行,使所有(我的意思是 100%)你的组件纯净。

我尝试按照您使用 Hapi.js+Folktale.js+Ramda 的方式创建服务器。我的想法最初起源于 Cycle.js。然而,我取得了轻微的成功。有些部分代码真的很笨拙而且写起来太局限了。之后,我放弃了纯路线。但是,我的其余代码是纯净的并且可读性很强。

最后一点,函数式编程是关于部分编码而不是整体编码。你或我正在尝试做的是从头到尾的函数式编程。 至少在 JavaScript 中这会让人觉得有点尴尬。

关于javascript - 具有函数式编程(纯路由)的 Express.js 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42304212/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com