Skip to content
Our Sponsors
Open in Anthropic

title: Handler - ElysiaJS head: - - meta - property: 'og:title' content: Handler - ElysiaJS

- - meta
  - name: 'description'
    content: 处理程序是一个响应每个路由请求的函数。接受请求信息并向客户端返回响应。处理程序可以通过 Elysia.get / Elysia.post 注册。

- - meta
  - property: 'og:description'
    content: 处理程序是一个响应每个路由请求的函数。接受请求信息并向客户端返回响应。处理程序可以通过 Elysia.get / Elysia.post 注册。

Handler

Handler - 一个接受 HTTP 请求并返回响应的函数。

typescript
import { Elysia } from 'elysia'

new Elysia()
    // 函数 `() => 'hello world'` 是一个处理程序
    .get('/', () => 'hello world')
    .listen(3000)

处理程序可以是字面量值,并且可以内联。

typescript
import { Elysia, file } from 'elysia'

new Elysia()
    .get('/', 'Hello Elysia')
    .get('/video', file('kyuukurarin.mp4'))
    .listen(3000)

使用内联值总是返回相同的值,这对于优化文件等静态资源的性能很有用。

这使得 Elysia 可以提前编译响应以优化性能。

TIP

提供内联值不是缓存。

静态资源值、标头和状态可以使用生命周期动态变更。

Context

Context 包含每个请求唯一的请求信息,除了 store (全局可变状态) 之外不共享。

typescript
import { 
Elysia
} from 'elysia'
new
Elysia
()
.
get
('/', (
context
) =>
context
.
path
)
// ^ 这是一个上下文

Context 只能在路由处理程序中检索。它包括:

Property

  • body - HTTP 消息、表单或文件上传。
  • query - 查询字符串,包含搜索查询的附加参数作为 JavaScript 对象。(查询是从路径名后以 '?' 问号符号开始的值中提取的)
  • params - Elysia 的路径参数,解析为 JavaScript 对象
  • headers - HTTP 标头,关于请求的附加信息,如 User-Agent、Content-Type、Cache Hint。
  • cookie - 用于与 Cookie 交互的全局可变信号存储(包括 get/set)
  • store - Elysia 实例的全局可变存储

Utility Function

  • redirect - 重定向响应的函数
  • status - 返回自定义状态码的函数
  • set - 应用于响应的属性:

Additional Property

status

一个返回自定义状态码并进行类型缩小的函数。

typescript
import { Elysia } from 'elysia'

new Elysia()
    .get('/', ({ status }) => status(418, "Kirifuji Nagisa"))
    .listen(3000)
localhost

GET

推荐使用永不抛出的方法返回status 而不是抛出,因为它:

  • 允许 TypeScript 检查返回值是否正确类型匹配响应模式
  • 基于状态码的类型缩小的自动补全
  • 使用端到端类型安全的错误处理类型缩小(Eden

Set

set 是一个可变属性,形成可通过 Context.set 访问的响应。

ts
import { 
Elysia
} from 'elysia'
new
Elysia
()
.
get
('/', ({
set
,
status
}) => {
set
.
headers
= { 'X-Teapot': 'true' }
return
status
(418, 'I am a teapot')
}) .
listen
(3000)

set.headers

允许我们追加或删除表示为对象的响应标头。

typescript
import { 
Elysia
} from 'elysia'
new
Elysia
()
.
get
('/', ({
set
}) => {
set
.
headers
['x-powered-by'] = 'Elysia'
return 'a mimir' }) .
listen
(3000)

TIP

Elysia 为小写提供自动补全以保持大小写敏感性一致性,例如使用 set-cookie 而不是 Set-Cookie

redirect 传统方式

将请求重定向到另一个资源。

typescript
import { 
Elysia
} from 'elysia'
new
Elysia
()
.
get
('/', ({
redirect
}) => {
return
redirect
('https://youtu.be/whpVWVWBW4U?&t=8')
}) .
get
('/custom-status', ({
redirect
}) => {
// 你也可以设置自定义状态进行重定向 return
redirect
('https://youtu.be/whpVWVWBW4U?&t=8', 302)
}) .
listen
(3000)

当使用 redirect 时,不需要返回值,将被忽略。因为响应将来自另一个资源。

set.status 传统方式

如果未提供,则设置默认状态码。

建议在只需要返回特定状态码同时允许用户返回自定义值的插件中使用。例如,HTTP 201/206 或 403/405 等。

typescript
import { 
Elysia
} from 'elysia'
new
Elysia
()
.
onBeforeHandle
(({
set
}) => {
set
.
status
= 418
return 'Kirifuji Nagisa' }) .
get
('/', () => 'hi')
.
listen
(3000)

status 函数不同,set.status 无法推断返回值类型,因此无法检查返回值是否正确类型匹配响应模式。

TIP

HTTP 状态表示响应的类型。如果路由处理程序成功执行且没有错误,Elysia 将返回状态码 200。

你也可以使用状态码的通用名称而不是数字来设置状态码。

typescript
// @errors 2322
import { 
Elysia
} from 'elysia'
new
Elysia
()
.
get
('/', ({
set
}) => {
set
.
status
return 'Kirifuji Nagisa' }) .
listen
(3000)

Elysia 提供了一个可变信号用于与 Cookie 交互。

没有 get/set,你可以提取 cookie 名称并直接检索或更新其值。

typescript
import { 
Elysia
} from 'elysia'
new
Elysia
()
.
get
('/set', ({
cookie
: {
name
} }) => {
// 获取
name
.
value
// 设置
name
.
value
= "New Value"
})

更多信息请参见 Patterns: Cookie

Redirect

将请求重定向到另一个资源。

typescript
import { 
Elysia
} from 'elysia'
new
Elysia
()
.
get
('/', ({
redirect
}) => {
return
redirect
('https://youtu.be/whpVWVWBW4U?&t=8')
}) .
get
('/custom-status', ({
redirect
}) => {
// 你也可以设置自定义状态进行重定向 return
redirect
('https://youtu.be/whpVWVWBW4U?&t=8', 302)
}) .
listen
(3000)

当使用 redirect 时,不需要返回值,将被忽略。因为响应将来自另一个资源。

Formdata

我们可以通过直接从处理程序返回 form 工具来返回 FormData

typescript
import { Elysia, form, file } from 'elysia'

new Elysia()
	.get('/', () => form({
		name: 'Tea Party',
		images: [file('nagi.web'), file('mika.webp')]
	}))
	.listen(3000)

如果需要返回文件或多部分表单数据,这种模式很有用。

Return a file

或者,你也可以直接返回 file 而不使用 form 来返回单个文件。

typescript
import { Elysia, file } from 'elysia'

new Elysia()
	.get('/', file('nagi.web'))
	.listen(3000)

Stream

通过使用带有 yield 关键字的生成器函数来返回开箱即用的流式响应。

typescript
import { Elysia } from 'elysia'

const app = new Elysia()
	.get('/ok', function* () {
		yield 1
		yield 2
		yield 3
	})

在这个例子中,我们可以使用 yield 关键字来流式传输响应。

Server Sent Events (SSE)

Elysia 通过提供 sse 工具函数支持服务器发送事件

typescript
import { 
Elysia
,
sse
} from 'elysia'
new
Elysia
()
.
get
('/sse', function* () {
yield
sse
('hello world')
yield
sse
({
event
: 'message',
data
: {
message
: 'This is a message',
timestamp
: new
Date
().
toISOString
()
}, }) })

当值被包装在 sse 中时,Elysia 会自动将响应标头设置为 text/event-stream 并将数据格式化为 SSE 事件。

Headers in Server-Sent Event

标头只能在第一个块被 yield 之前设置。

typescript
import { 
Elysia
} from 'elysia'
const
app
= new
Elysia
()
.
get
('/ok', function* ({
set
}) {
// 这将设置标头
set
.
headers
['x-name'] = 'Elysia'
yield 1 yield 2 // 这将什么都不做
set
.
headers
['x-id'] = '1'
yield 3 })

一旦第一个块被 yield,Elysia 会将标头发送给客户端,因此在第一个块被 yield 之后变更标头将没有任何作用。

Conditional Stream

如果响应在没有 yield 的情况下返回,Elysia 会自动将流转换为普通响应。

typescript
import { Elysia } from 'elysia'

const app = new Elysia()
	.get('/ok', function* () {
		if (Math.random() > 0.5) return 'ok'

		yield 1
		yield 2
		yield 3
	})

这允许我们有条件地流式传输响应或在必要时返回普通响应。

Automatic cancellation

在响应流式传输完成之前,如果用户取消请求,Elysia 会自动停止生成器函数。

Eden

Eden 会将流响应解释为 AsyncGenerator,允许我们使用 for await 循环来消费流。

typescript
import { 
Elysia
} from 'elysia'
import {
treaty
} from '@elysiajs/eden'
const
app
= new
Elysia
()
.
get
('/ok', function* () {
yield 1 yield 2 yield 3 }) const {
data
,
error
} = await
treaty
(
app
).
ok
.
get
()
if (
error
) throw
error
for await (const
chunk
of
data
)
console
.
log
(
chunk
)

Request

Elysia 构建在 Web 标准 Request 之上,它在 Node、Bun、Deno、Cloudflare Worker、Vercel Edge Function 等多个运行时之间共享。

typescript
import { Elysia } from 'elysia'

new Elysia()
	.get('/user-agent', ({ request }) => {
		return request.headers.get('user-agent')
	})
	.listen(3000)

允许你在必要时访问低级请求信息。

Server 仅限 Bun

服务器实例是 Bun 服务器实例,允许我们访问服务器信息,如端口号或请求 IP。

只有在 HTTP 服务器使用 listen 运行时,服务器才可用。

typescript
import { Elysia } from 'elysia'

new Elysia()
	.get('/port', ({ server }) => {
		return server?.port
	})
	.listen(3000)

Request IP 仅限 Bun

我们可以使用 server.requestIP 方法获取请求 IP

typescript
import { Elysia } from 'elysia'

new Elysia()
	.get('/ip', ({ server, request }) => {
		return server?.requestIP(request)
	})
	.listen(3000)

Extends context 高级概念

Elysia 默认提供最小的 Context,允许我们使用 state、decorate、derive 和 resolve 为我们的特定需求扩展 Context。

有关如何扩展 Context 的更多信息,请参见 Extends Context