localhost
GET
Elysia 是一个用于构建后端服务器的符合人体工学的 Web 框架,旨在与 Bun 配合使用。
Elysia 以简单性和类型安全为设计理念,拥有熟悉的 API,并广泛支持 TypeScript,针对 Bun 进行了优化。
以下是在 Elysia 中的简单 hello world 示例。
import { Elysia } from 'elysia'
new Elysia()
.get('/', '你好 Elysia')
.get('/user/:id', ({ params: { id }}) => id)
.post('/form', ({ body }) => body)
.listen(3000)
打开 localhost:3000,结果应该显示 '你好 Elysia'。
GET
TIP
将鼠标悬停在代码片段上以查看类型定义。
在 mock 浏览器中,点击蓝色路径以更改路径并预览响应。
Elysia 可以在浏览器中运行,您看到的结果实际上是使用 Elysia 运行的。
基于 Bun 及诸多优化(如静态代码分析),Elysia 能够动态生成优化后的代码。
Elysia 的性能优于当今大多数 Web 框架[1],甚至可以与 Golang 和 Rust 框架的性能相匹配[2]。
框架 | 运行时 | 平均 | 普通文本 | 动态参数 | JSON 数据 |
---|---|---|---|---|---|
bun | bun | 262,660.433 | 326,375.76 | 237,083.18 | 224,522.36 |
elysia | bun | 255,574.717 | 313,073.64 | 241,891.57 | 211,758.94 |
hyper-express | node | 234,395.837 | 311,775.43 | 249,675 | 141,737.08 |
hono | bun | 203,937.883 | 239,229.82 | 201,663.43 | 170,920.4 |
h3 | node | 96,515.027 | 114,971.87 | 87,935.94 | 86,637.27 |
oak | deno | 46,569.853 | 55,174.24 | 48,260.36 | 36,274.96 |
fastify | bun | 65,897.043 | 92,856.71 | 81,604.66 | 23,229.76 |
fastify | node | 60,322.413 | 71,150.57 | 62,060.26 | 47,756.41 |
koa | node | 39,594.14 | 46,219.64 | 40,961.72 | 31,601.06 |
express | bun | 29,715.537 | 39,455.46 | 34,700.85 | 14,990.3 |
express | node | 15,913.153 | 17,736.92 | 17,128.7 | 12,873.84 |
Elysia 旨在帮助你编写更少的 TypeScript。
Elysia 的类型系统经过微调,可以自动推断你的代码类型,而无需编写显式的 TypeScript,同时提供运行时和编译时的类型安全,以提供最佳的开发者体验。
看这个例子:
import { Elysia } from 'elysia'
new Elysia()
.get('/user/:id', ({ params: { id } }) => id)
.listen(3000)
上述代码创建了一个路径参数 "id",替换 :id
的值将被作为 params.id
传递,在运行时和类型中无需手动声明类型。
GET
Elysia 的目标是帮助你编写更少的 TypeScript,并更多地关注业务逻辑。让复杂的类型处理交给框架。
使用 Elysia 并不需要 TypeScript,但建议使用 TypeScript。
为了更进一步,Elysia 提供 Elysia.t,一个架构构建器,用于在运行时和编译时验证类型和值,以创建数据类型的单一真实来源。
让我们修改之前的代码,仅接受数字值,而不是字符串。
import { Elysia, t } from 'elysia'
new Elysia()
.get('/user/:id', ({ params: { id } }) => id, {
params: t.Object({
id: t.Numeric()
})
})
.listen(3000)
这段代码确保我们的路径参数 id 永远是一个数字字符串,然后在运行时和编译时(类型级别)自动将其转换为数字。
TIP
将鼠标悬停在上述代码片段中的 "id" 以查看类型定义。
使用 Elysia 架构构建器,我们可以确保类型安全,如同强类型语言,且具有单一真实来源。
Elysia 默认采用许多标准,如 OpenAPI 和 WinterCG 合规,允许你与大多数行业标准工具集成,或至少与你熟悉的工具轻松集成。
例如,因为 Elysia 默认采用 OpenAPI,生成 Swagger 文档就像添加一行代码一样简单:
import { Elysia, t } from 'elysia'
import { swagger } from '@elysiajs/swagger'
new Elysia()
.use(swagger())
.get('/user/:id', ({ params: { id } }) => id, {
params: t.Object({
id: t.Number()
})
})
.listen(3000)
使用 Swagger 插件,你可以轻松生成一个 Swagger 页面,而无需额外代码或特定配置,并轻松与团队分享。
使用 Elysia,类型安全不仅限于服务器端。
使用 Elysia,你可以像 tRPC 一样自动与前端团队同步你的类型,使用 Elysia 的客户端库 "Eden"。
import { Elysia, t } from 'elysia'
import { swagger } from '@elysiajs/swagger'
const app = new Elysia()
.use(swagger())
.get('/user/:id', ({ params: { id } }) => id, {
params: t.Object({
id: t.Number()
})
})
.listen(3000)
export type App = typeof app
在你的客户端代码中:
// client.ts
import { treaty } from '@elysiajs/eden'
import type { App } from './server'
const app = treaty<App>('localhost:3000')
// 从 /user/617 获取数据
const { data } = await app.user({ id: 617 }).get()
console.log(data)
使用 Eden,你可以使用现有的 Elysia 类型来查询 Elysia 服务器 无需代码生成,并自动同步前后端的类型。
Elysia 不仅仅是帮助你创建一个可靠的后端,还关乎这个世界上美好的事物。
Elysia 最初是为 Bun 设计的,但 不限于 Bun。因为 Elysia 符合 WinterCG,你可以将 Elysia 服务器部署在 Cloudflare Workers、Vercel Edge Functions 和其他支持 Web 标准请求的运行时上。
如果你有关于 Elysia 的问题或遇到困难,请随时在我们的 GitHub Discussions、Discord 和 Twitter 上提问。
1. 测量请求/秒。基于在 Debian 11 上进行的查询、路径参数解析和设置响应头的基准测试,Intel i7-13700K 测试于 2023 年 8 月 6 日,基于 Bun 0.7.2。有关基准测试条件,请参见 此处。