Skip to content
Our Sponsors
Open in Anthropic
Blog

Elysia 1.4 - 超对称性

'Elysia 1.4' 作为标题,左侧有 'Supersymmetry' 一词,右侧有 ElysiaJS chan。

以 Sta 的歌曲 Supersymmetry(Tone Sphere 的结局主题曲)命名。

Elysia 1.4 的亮点是引入了标准 Schema 和 “类型健全性”

标准 Schema

在过去的 3 年中,Elysia 一直使用 TypeBox 作为唯一的验证器。它因其性能和类型推断而成为 Elysia 最受欢迎的功能之一。

然而,从一开始社区最常请求的功能之一(elysia#20)就是支持除 TypeBox 以外的其他验证器。

由于 Elysia 与 TypeBox 深度绑定,为每个验证器单独添加支持需要大量努力,并进行持续维护以跟上变化。

幸运的是,一个名为 Standard Schema 的新提案定义了一种使用相同 API 与不同 Schema 的标准方式。这使我们能够支持多个验证器,而无需为每个验证器编写自定义集成。

Elysia 现在支持标准 Schema,允许您使用您喜欢的验证器,例如:

  • Zod
  • Valibot
  • Effect Schema
  • ArkType
  • Joi
  • 以及更多!

您可以以类似于 TypeBox 的方式提供 Schema,它将开箱即用:

ts
import { 
Elysia
,
t
} from 'elysia'
import {
z
} from 'zod'
import * as
v
from 'valibot'
const
app
= new
Elysia
()
.
post
(
'/user/:id', ({
body
,
params
}) => {
body
params
}, {
params
:
z
.
object
({
id
:
z
.
coerce
.
number
()
}),
body
:
v
.
object
({
name
:
v
.
literal
('lilith')
}) })

您可以在单个路由中使用多个验证器,它们将无缝协作并具有正确的类型推断。

OpenAPI

有一个请求是支持使用标准 Schema 为 OpenAPI 生成 JSON Schema,但尚未实现。

然而,我们为 openapi 提供了自定义 mapJsonSchema,允许您提供自定义函数来将 Schema 映射到 JSON Schema 作为变通方法。

这允许您使用您喜欢的验证器生成美丽的 OpenAPI 文档。

Zod 与 OpenAPI 支持

使用 Zod 的原生 OpenAPI Schema 支持和 describe 来为 Schema 添加描述

但是,如果您的验证器不支持 JSON Schema,我们提供 OpenAPI 类型生成 来直接从验证器的 TypeScript 类型生成 OpenAPI Schema。

这意味着 Elysia 支持所有支持标准 Schema 的验证器的 OpenAPI 生成,即使它们不直接支持 JSON Schema。

Valibot 与 OpenAPI 支持

Valibot 不直接支持 JSON Schema,但我们使用 OpenAPI 类型生成来处理它

它不仅会生成正确的输入类型,还会生成所有可能的输出类型,包括错误响应。

这是 Elysia 的独特功能,我们为提供它感到非常自豪。

独立验证器

您还可以使用独立验证器来使用多个 Schema 验证单个输入:

ts
import { 
Elysia
,
t
} from 'elysia'
import {
z
} from 'zod'
import * as
v
from 'valibot'
const
app
= new
Elysia
()
.
guard
({
schema
: 'standalone',
body
:
z
.
object
({
id
:
z
.
coerce
.
number
()
}) }) .
post
(
'/user/:id', ({
body
}) =>
body
,
{
body
:
v
.
object
({
name
:
v
.
literal
('lilith')
}) } )

此示例使用 Zod 和 Valibot 两者来验证 body,允许您在代码库中使用来自不同验证器的现有 Schema 一起使用。

这通过使用每个验证器解析输入的一部分,然后将每个结果存储为快照合并在一起形成单个输出来工作,从而确保类型完整性。

使用多个验证器验证 body 的部分

使用 TypeBox、Zod、Valibot、Joi、Yup、ArkType、Effect Schema、TypeMap 和 ReScript Schema 来验证 body 的不同部分

我们同时测试了 8 个验证器,对输入的每个部分进行验证,它完美无缺地工作。

我们为开箱即用支持标准 Schema 而自豪。这是 Elysia 不绑定到单个验证器的重要一步,我们很兴奋看到您将用它构建什么。

宏是 Elysia 最强大和最灵活的功能之一。

它允许您定义可以修改和扩展 Elysia 功能的自定义属性,使您能够创建您喜欢的“子框架”。

宏的多功能性真正令人惊叹,让您轻松实现其他框架几乎不可能的事情。

随着 Elysia 1.4 的到来,我们带来了几项改进,使宏更加多功能。

宏 Schema

您现在可以为您的宏定义 Schema,允许您直接从宏添加自定义验证。

带有 Schema 的宏

带有 Schema 支持的宏

带有 Schema 的宏将自动验证和推断类型以确保类型安全,并且它可以与现有 Schema 共存。

您还可以堆叠来自不同宏的多个 Schema,甚至来自标准 Schema,它们将无缝协作。

宏 Schema 还支持 同一宏内的生命周期 的类型推断 由于 TypeScript 的限制,仅适用于命名单个宏。

带有扩展的宏

使用命名单个宏来将类型推断到同一宏内的生命周期

如果您想在同一宏内使用生命周期类型推断,您应该使用命名单个宏而不是多个堆叠宏。

不要与使用宏 Schema 将类型推断到路由的生命周期事件混淆。那完全没问题——此限制仅适用于在同一宏内使用生命周期。

宏扩展

您现在可以扩展现有宏,允许您基于现有功能构建。

带有扩展的宏

带有扩展支持的宏

这允许您基于现有宏构建并为其添加更多功能。

它还递归工作并自动去重,允许您扩展已经扩展其他宏的现有宏而不会出现任何问题。

然而,如果您不小心创建了循环依赖,Elysia 有 16 的栈限制来防止运行时和类型推断中的无限循环。

宏细节

您现在可以为您的宏定义 OpenAPI 细节,允许您直接从宏向 OpenAPI 文档添加更多细节。

如果路由已经具有 OpenAPI 细节,它将合并细节但优先使用路由细节而不是宏细节。

生命周期类型健全性

OpenAPI 类型生成 引入以来,它直接从类型生成 OpenAPI Schema,我们意识到为每个生命周期事件具有类型健全性会很棒。

这样,我们可以准确记录每个生命周期事件和宏的返回类型,代表单个路由可以返回的所有可能性。

通过重构 3000 多行纯类型、协调响应状态类型、为所有生命周期 API 包括类型级别的单元测试以确保类型完整性,以及优化类型性能,我们确保类型推断不会变慢。

所有这些复杂成就允许我们记录单个路由可以返回的所有可能性。

类型健全性

记录单个路由可以返回的所有可能性

这不仅改善了开发者体验,还通过确保 API 文档和 Eden Treaty 中的客户端考虑所有可能性来提高代码库的可靠性。

类型健全性覆盖所有生命周期事件和宏,允许您拥有完整的 API 文档。唯一的例外是由于性能原因的内联生命周期事件。

我们还设法将类型推断性能提高了约 9-11%,并将类型实例化减少了 11.5%,尽管类型复杂性大幅增加。

类型推断

类型实例化从我们的内部基准减少了 11.57%

组独立 Schema

以前,带有 Schema 的 group 使用覆盖策略,这意味着如果您在 group 中定义了 Schema,它将覆盖路由中的现有 Schema。

如果您想定义新 Schema,您必须手动包含现有 Schema。这不是很人性化,如果您忘记包含现有 Schema 可能会导致错误。

从 1.4 开始,带有 Schema 的 group 使用独立策略,这意味着如果您在 group 中定义 Schema,它不会覆盖而是与路由 Schema 共存。

组独立

带有 Schema 的 group 将与路由 Schema 共存

这允许您在 group 中定义新 Schema 而无需手动包含现有 Schema。

值得注意的变化

我们在 1.3.9 中关闭了大约 300 个问题,因此 1.4 中没有太多 bug 修复——我们已经解决了大多数已知问题。

改进

  • #861 在定义 GET 路由时自动添加 HEAD 方法
  • #1389 引用模型中的 NoValidate

变化

  • 出于安全原因,ObjectString/ArrayString 不再产生默认值
  • Cookie 现在在格式可能是 JSON 时动态解析
  • 导出 fileType 用于外部文件类型验证以获得准确响应

破坏性变化

  • 由于缺乏类型健全性,移除宏 v1
  • 移除 error 函数;改用 status
  • mapResponseafterResponse 中的 response 弃用通知;改用 responseValue

后记

这是我们第一次在发布说明封面图像中展示我们的吉祥物 Elysia chan!这也将成为未来发布说明的传统!

我们的封面艺术镜像了 Supersymmetry (音乐) 封面艺术的主题,其中 ElysiaJS chan 以类似姿势镜像 Weirs。

Elysia chan 镜像 Supersymmetry

Elysia chan 镜像 Supersymmetry 封面艺术中 Weirs 的相同姿势 (pixiv)

她是不是很可爱?我真的很喜欢她的样子!我个人努力提高了我的艺术技能来画她。希望你喜欢!

总之,我希望你喜欢这个版本!我们很兴奋看到你将用它构建什么!

祝你有愉快的一天!

我是全部

在这个微小的微观宇宙中

你苦乐参半的心灵的每一口

我爱全部


你知道

这个生命的游戏是我们的“riverrun,”

你是我这次旅程的幸运朋友


剩下的时间不多了

天空显示出它的褪色

星星游行

是时候改变我们的命运了

Elysia: Ergonomic Framework for Humans