今天给大家介绍一个我最近开发的新项目——Farrow。一款类型友好的函数式风格 Node.js Web 服务框架。
项目动机
在当下的 Node.js 开源生态里,已经有 expressjs, koajs, hapi, restify, fastify,nestjs 等或许数不胜数的 Web 服务框架,我们还需要另一个吗?
答案可能因人而异,在此分享一下我的个人看法。
Node.js 里大部分流行的 Web 服务框架,是在 TypeScript 真正流行之前,用 JavaScript 的视角下所开发。
它们充分发挥了 JavaScript 动态类型的表达能力,这毋庸置疑。
如果我们把——充分发挥 Static Type-System 的能力,在 Compile-Time 去尽可能捕获潜在的问题——也列入 Web 框架的考量范畴,那么用 TypeScript 重新开发一个 Web 服务框架,或许是一个值得尝试的事情。
Farrow 就是我在这个方向上的一个产出。
TypeScript 视角下的中间件设计
Rollup 和 Svelte 的作者 Rich Harris 最近分享了他对 Next-gen Node HTTP APIs 的看法[0], 我深受启发。
事情源于 Wes 的一条推特投票:
接近 70% 的开发者,选择了 expressjs 风格的中间件函数设计。一个压倒性的选择。
而 Rich Harris 所选的,只有 14.5% 的支持率。
在那条 Gist 里,Rich Harris 解释了他不喜欢第一个选项的原因。大致是:
1、总是需要丑陋的传递 res 参数
2、组合中间件的时候,常常要对 res 做 monkey-patching
他给出了他觉得更好的另一种设计。
简单地说,就是取消 res 参数,只保留 req 参数,通过 return response 表达响应结果,通过 return void/undefined 表达调用下一个中间件 next()。
另一位开发者 Oliver Ash 在推特上,也指出了 expressjs 的中间件设计的一个不足指出——没有充分利用 Compile-Time 的排查能力[1]。
简单地说,当 response 是 middleware 的返回值时,TypeScript 可以从类型上约束,每个请求都必须有个返回值,而不必担心遗漏。
fp-ts 的作者 Giulio Canti 对此也有他的尝试——hyper-ts[3]。hyper-ts 受到 purescript 的 hyper 项目的启发,利用 TypeScript 的 Type-System,可以规避一些常见的错误,比如:
这些线索都指向一个结论:或许可以用函数式风格(immutable way)去设计 HTTP 中间件 API。
Farrow-Pipeline:类型友好的中间件函数设计
Farrow 的中间件函数受到了 Koa 中间件的启发,但又有所不同。
从上图中,我们可以了解到以下信息:
1)Response 不在中间件函数的参数中,而是来自 farrow-htpp 模块导出的朴素函数。
2)response 是中间件函数的返回值,可以在 Compile-Time 得到检查。
如果没有返回值,会像下面这样:
如果返回错误的值,会像下面这样:
必须通过 Response.{method}() 的方式,对客户端做出响应:
Response 的 API 设计,支持 Method Chaining,可以像下面那样调用:
如上,设置 response status,设置 response headers,设置 response cookie,设置 response content,都可以优雅地编写到一起。
那么,在 Farrow 中,多个中间件之间又是如何协作的呢?
比如,在上游中间件中,给下游中间件传递新的 request,像下面这样:
Farrow 中间件函数的第二个参数是 next 函数,跟 expressjs/koajs 的中间件函数不同,Farrow 中间件函数,既有参数,又有返回值。
其参数为可选的 request,其返回值为 response。
当 next() 调用没有传递参数时,下游中间件拿到的 request 跟上游中间件的一样。
当调用 next 时传递新的 request,下游中间件将拿到新的 request 对象。
通过这个很自然的参数传递机制,我们不必修改当前的 request。甚至,Farrow 将 request 的类型,设置为 readonly。
Farrow 鼓励保持 request/response 的 immutable 状态。
同理,我们也可以在上游中间件中,过滤或者操作下游中间件返回的 response,像下面这样做:
Response 对象提供了 merge 方法,合以方便地合并多个 response 里的 status, headers, cookies, content 等组成部分。
Farrow 还提供了支持分形的 Router 设计,可以帮助我们细粒度地分割业务逻辑到不同的模块,并能有机地组合它们。
Farrow-Schema:类型安全的 Routing 设计
Farrow 实现了一个强大而又灵活的 Schema-Based Validation,可以类型安全的方式,匹配特定的 request 对象。
基本用法如下所示:
http.match 方法接受参数为 { pathname, method, query, params, headers, cookies } 对象,构成一个 Request Schema。
其中 schema.pathname 采用了 expressjs-like 的 path-to-regexp 写法。
Farrow 会根据 Request Schema,通过 type infer 提取出匹配的 request 对象的精确类型,并且在 runtime 里做 validate,保证 request 对象的类型安全。
此外,Farrow 还基于 TypeScript V4.1 的 Template Literal Types 特性,实现了类型安全的 route matching。
在 path 中通过
更复杂一点的案例如下所示:
当
当
想要更了解 Farrow 的 Router-Url-Schema,可以查看它的文档[3]。
Farrow-Hooks 机制
在 Farrow 里,另一个值得一提的特性是,我们参考了 React-Hooks 的设计思路,提供了 Farrow-Hooks 机制,用以整合服务器的其它部分,如 logger, database-connection 等。
相比 koajs 通过 mutable ctx 参数去挂载拓展的方法,在 Farrow 里,context 不是参数,而是 Hooks。
就像 React-Hooks 的 useState,可以看作是把 class-component 里共享的 this.state 做细粒度的切割。
Farrow 里的 Context.use 将共享的 ctx,也做如此切割。如下所示:
我们定义了一个 User 类型,以类似 React.createContext 的方式,创建了一个 Farrow Context,并提供默认值(此处是 null)。
通过 UserContext.use() 这个内置的 hooks,可以访问到对应的 user context。在每一次 request -> response 的过程中,所有 Context 都是新的、独立的。
我们不再具有一个大的 ctx,而是多个小的 Context 单元。
我们可以基于 Context.use() 封装自定义的 hooks,如上图的 useUser。
动态更新 Context 的 value,则像下面这样做。
实现一个 Provider Middleware,可以动态的、异步的更新 context value,让下游中间件消费。其中的关系类似于 React Context 里的 Provider 和 Consumer。 上游中间件是 Context Provider,下游中间件是 Context Consumer。
通过 Context Hooks 机制,我们的中间件函数类型始终是简单和稳定的,它只关注 request -> response 的处理,其它附加事物,可以按需通过 Hooks 去提供。
Farrow-React:内置的组件化 SSR
Farrow 提供了一个官方 SSR 库——farrow-react。当然,你也可以根据 Response.html 或 Response.stream 等方法,去构建自己的 SSR 库。
如上所示,farrow-react 提供了一个 Farrow-Hooks,通过 useReactView 我们获取到了一个 ReactView 对象,通过它的 render 方法,可以将 JSX 渲染成 html 并通过 farrow-http 发送给浏览器。
farrow-react 提供了 Link 组件,可以帮助我们处理 prefix 相关的自动补全。想要了解更多,可以查看 farrow 官方文档。
总结
至此,我们大致介绍了 Farrow 的几个核心特征。
Farrow 的目标并不止步于此,未来我们将构建更多的 farrow 生态。比如:
1)farrow-restapi 和 farrow-restapi-client,支持在 client project 中复用 server project 的 schema/type,实现 server/client 两个端数据传递上的 type safe 功能。
2)farrow-graphql 和 farrow-graphql-client,类似于 farrow-restapi 但支持通过 graphql 去实现。
3)farrow-server-component,支持 React Server Component。
要做的工作还很多,如果你也感兴趣,欢迎一起来为 Farrow 项目做贡献[4]。
[0] Next-gen Node HTTP APIs
https://twitter.com/Rich_Harris/status/1304082928490733573
[1] Oliver Ash
https://twitter.com/OliverJAsh/status/1304138283686002689
[2] hyper-ts: Type safe middleware architecture for HTTP servers
https://github.com/gcanti/hyper-ts
[3] Farrow Router-Url-Schema
https://github.com/Lucifier129/farrow/blob/master/docs/http.md#router-url-schema
[4] Farrow: A type friendly web framework for node.js written by TypeScript
https://github.com/Lucifier129/farrow
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/5Nl5Up87KkO1Y2QY8_mPuQ
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。