Skip to content
Blog

Elysia 0.4 - 月夜の音楽会 (Moonlit Night Concert)

shattered glass pieces floating in the abyss

以 Shikata Akiko 创作并演唱的《"说谎的公主与盲目的王子" 预告片》和《「月夜の音楽会」(月夜音乐会)》的片头曲命名。

¥Named after the opening music of "The Liar Princess and the Blind Prince" trailer, 「月夜の音楽会」(Moonlit Night Concert) composed and sang by Akiko Shikata.

此版本并未引入任何激动人心的新功能,而是为 Elysia 未来的更坚实基础和内部改进奠定了基础。

¥This version doesn't introduce an exciting new feature, later but a foundation for more solid ground, and internal improvement for the future of Elysia.

提前兼容

¥Ahead of Time Complie

默认情况下,Elysia 必须在各种情况下处理条件检查,例如,在执行之前检查路由的生命周期是否存在,或者在提供验证模式的情况下解包验证模式。

¥By default, Elysia has to deal with conditional checking in various situations, for example, checking if the life-cycle of the route existed before performing, or unwrapping validation schema if provided.

这给 Elysia 和整体带来了最小的开销,因为即使路由没有附加生命周期事件,也需要在运行时进行检查。

¥This introduces a minimal overhead to Elysia and overall because even if the route doesn't have a life-cycle event attached to it, it needs to be runtime checked.

由于每个函数都在编译时进行检查,因此不可能存在条件异步。例如,一个返回文件的简单路由应该同步,但由于是编译时检查,某些路由可能是异步的,从而导致相同的简单路由也异步。

¥Since every function is checked on compile time, it's not possible to have a conditional async, for example, a simple route that returns a file should be synced, but since it's compile-time checking, some routes might be async thus making the same simple route async too.

异步函数会给函数引入额外的 tick,使其速度稍慢。由于 Elysia 是 Web 服务器的基础,我们希望优化每个部分,以确保你不会遇到性能问题。

¥An async function introduces an additional tick to the function, making it a bit slower. But since Elysia is a foundation for web servers, we want to optimize every part to make sure that you don't run into performance problems.

我们通过引入提前编译 (Ahead Time Compilation) 解决了这个小开销。

¥We fix this small overhead by introducing Ahead Time Compilation.

顾名思义,Elysia 不是在运行时检查动态生命周期和验证,而是检查生命周期、验证以及异步函数的可能性,并生成一个紧凑的函数,删除了不必要的部分,例如未使用的生命周期和验证。

¥As the name suggests, instead of checking dynamic life-cycle and validation on the runtime, Elysia checks life-cycle, validation, and the possibility of an async function and generates a compact function, removing an unnecessary part like an un-used life-cycle and validation.

使条件异步函数成为可能,因为我们不再使用集中式函数进行处理,而是为每个路由专门创建一个新函数。Elysia 随后会检查所有生命周期函数和处理程序,查看是否存在异步操作,如果没有,则会同步该函数以减少额外开销。

¥Making conditional async function possible, since instead of using a centralized function for handling, we compose a new function especially created for each route instead. Elysia then checks all life-cycle functions and handlers to see if there's an async, and if not, the function will be synced to reduce additional overhead.

TypeBox 0.26

TypeBox 是一个库,它支持 Elysia 的验证和类型提供程序,以创建类型级别的单一事实来源,并重新导出为 Elysia.t。

¥TypeBox is a library that powered Elysia's validation and type provider to create a type-level single source of truth, re-exported as Elysia.t.

在本次更新中,我们将 TypeBox 从 0.25.4 更新到 0.26。

¥In this update, we update TypeBox from 0.25.4 to 0.26.

这带来了许多改进和新功能,例如,我们可能会在 Elysia 的下一个版本中支持 Not 类型和 Convert 对应 coercion 值。

¥This brings a lot of improvement and new features, for example, a Not type and Convert for coercion value which we might support in some next version of Elysia.

但 Elysia 的一个好处是,Error.First() 允许我们获取第一个类型错误,而不是使用迭代器,这减少了创建新错误并发送回客户端的开销。

¥But the one benefit for Elysia would be, Error.First() which allows us to get the first error of type instead of using Iterator, this reduces overhead in creating a new Error to send back to the client.

TypeBox 和 Elysia.t 有一些更改,通常不会对你造成太大影响,但你可以查看 TypeBox 发布在这里。 中的新功能。

¥There are some changes to TypeBox and Elysia.t that normally wouldn't have much effect on your end, but you can see what's a new feature in TypeBox release here.

按状态验证响应

¥Validate response per status

之前,Elysia 的响应使用联合类型验证多个状态响应。

¥Previously, Elysia's response validate multiple status responses using union type.

对于高度动态且对状态响应严格的应用,这可能会产生意想不到的结果。例如,如果你有如下路由:

¥This might have unexpected results for highly dynamic apps with a strict response for status. For example if you have a route like:

ts
app.post('/strict-status', process, {
    schema: {
        response: {
            200: t.String(),
            400: t.Number()
        }
    }
})

如果 200 响应不是字符串,则预期会抛出验证错误,但实际上,它不会抛出错误,因为响应验证使用的是联合。这可能会给终端用户留下一个意想不到的值,并导致 Eden Treaty 的类型错误。

¥It's expected that if 200 response is not a string, then it should throw a validation error, but in reality, it wouldn't throw an error because response validation is using union. This might leave an unexpected value to the end user and a type error for Eden Treaty.

在此版本中,响应将按状态而非联合进行验证,这意味着它将严格基于响应状态而非联合类型进行验证。

¥With this release, a response is validated per status instead of union, which means that it will strictly validate based on response status instead of unioned type.

Elysia 分离 Fn

¥Separation of Elysia Fn

Elysia Fn 是 Elysia 的一个很好的补充,它与 Eden 结合,打破了客户端和服务器之间的界限,允许你在客户端使用任何服务器端函数,完全类型安全,甚至可以使用 Error、Set 和 Map 等原始类型。

¥Elysia Fn is a great addition to Elysia, with Eden, it breaks the boundary between client and server allowing you to use any server-side function in your client, fully type-safe and even with primitive types like Error, Set, and Map.

但是,由于支持原始类型,Elysia Fn 依赖于 "superjson",而 "superjson" 大约占 Elysia 依赖大小的 38%。

¥But with the primitive type support, Elysia Fn depends on "superjson" which is around 38% of Elysia's dependency size.

在此版本中,要使用 Elysia Fn,你需要明确安装 @elysiajs/fn 才能使用 Elysia Fn。这种方法就像安装与 cargo add --feature 相同的附加功能。

¥In this release, to use Elysia Fn, you're required to explicitly install @elysiajs/fn to use Elysia Fn. This approach is like installing an additional feature same as cargo add --feature.

这使得 Elysia 对于不使用 Elysia Fn 的服务器来说更轻量级,遵循我们的理念,确保你拥有真正需要的东西。

¥This makes Elysia lighter for servers that don't use Elysia Fn, Following our philosophy, To ensure that you have what you actually need

但是,如果你忘记安装 Elysia Fn 并意外使用 Elysia Fn,则会出现类型警告,提醒你在使用前安装 Elysia Fn,并且会出现运行时错误,提示你安装 Elysia Fn。

¥However, if you forgot to install Elysia Fn and accidentally use Elysia Fn, there will be a type warning reminding you to install Elysia Fn before usage, and a runtime error telling the same thing.

对于迁移,除了明确安装 @elysiajs/fn 这一重大变更外,无需进行迁移。

¥For migration, besides a breaking change of installing @elysiajs/fn explicitly, there's no migration need.

条件路由

¥Conditional Route

此版本引入了 .if 方法,用于注册条件路由或插件。

¥This release introduces .if method for registering a conditional route or plugin.

这允许你以声明方式执行特定条件,例如从生产环境中排除 Swagger 文档。

¥This allows you to declaratively for a specific conditional, for example excluding Swagger documentation from the production environment.

ts
const isProduction = process.env.NODE_ENV === 'production'

const app = new Elysia().if(!isProduction, (app) =>
    app.use(swagger())
)

Eden Treaty 将能够像识别普通路由/插件一样识别该路由。

¥Eden Treaty will be able to recognize the route as if it's a normal route/plugin.

自定义验证错误

¥Custom Validation Error

非常感谢 #31 上的 amirrezamahyari,它允许 Elysia 访问 TypeBox 的错误属性,从而实现更好的编程式错误响应。

¥Big thanks to amirrezamahyari on #31 which allows Elysia to access TypeBox's error property, for a better programmatically error response.

ts
new Elysia()
    .onError(({ code, error, set }) => {
        if (code === 'NOT_FOUND') {
            set.status = 404

            return 'Not Found :('
        }

        if (code === 'VALIDATION') {
            set.status = 400

            return {
                fields: error.all()
            }
        }
    })
    .post('/sign-in', () => 'hi', {
        schema: {
            body: t.Object({
                username: t.String(),
                password: t.String()
            })
        }
    })
    .listen(3000)

现在你可以为你的 API 创建验证错误,而不仅限于第一个错误。

¥Now you can create a validation error for your API not limited to only the first error.


显著改进:

¥Notable Improvement:

  • 将 TypeBox 更新至 0.26.8

  • 内联响应类型声明

  • 重构某些类型以加快响应速度

  • 使用 Typebox Error().First() 代替迭代

  • 添加 innerHandle,用于返回实际响应(用于基准测试)

重大变更:

¥Breaking Change:

  • .fn@elysiajs/fn 分开

之后

¥Afterward

此版本可能不是一个带有令人兴奋的新功能的重大版本,但它为我未来计划的 Elysia 奠定了坚实的基础和概念验证,并使 Elysia 比以前更快、更通用。

¥This release might not be a big release with a new exciting feature, but this improve a solid foundation, and Proof of Concept for planned I have for Elysia in the future, and making Elysia even faster and more versatile than it was.

我对未来充满期待。

¥I'm really excited for what will be unfold in the future.

感谢你一直以来对 Elysia 的支持~

¥Thank you for your continuous support for Elysia~

月夜演唱会,我们的秘密

让我们重新开始,不要放手。

月夜演唱会,我们的羁绊

我想告诉你,“你不是骗子”

我心中的回忆就像花朵般不断绽放

无论你长什么样,你都是我的歌姬

今晚在我身边

Elysia: Ergonomic Framework for Humans