封装
Elysia 钩子仅封装到其自身实例。
如果您创建新实例,它不会与其他实例共享钩子。
ts
import { Elysia } from 'elysia'
const profile = new Elysia()
.onBeforeHandle(
({ query: { name }, status }) => {
if(!name)
return status(401)
}
)
.get('/profile', () => 'Hi!')
new Elysia()
.use(profile)
.patch('/rename', () => 'Ok! XD')
.listen(3000)尝试在 URL 栏中将路径更改为 /rename 并查看结果
Elysia 隔离生命周期,除非明确声明。
这类似于 JavaScript 中的 export,您需要导出函数以使其在模块外可用。
要将生命周期**"导出"**到其他实例,您必须添加指定作用域。
作用域
有 3 个可用作用域:
- local(默认)- 仅应用于当前实例和后代
- scoped - 应用于父级、当前实例和后代
- global - 应用于所有应用该插件的实例(所有父级、当前和后代)
在我们的例子中,我们想将登录检查应用到作为直接父级的 app,因此我们可以使用 scoped 或 global。
ts
import { Elysia } from 'elysia'
const profile = new Elysia()
.onBeforeHandle(
{ as: 'scoped' },
({ cookie }) => {
throwIfNotSignIn(cookie)
}
)
.get('/profile', () => 'Hi there!')
const app = new Elysia()
.use(profile)
// 这里有登录检查
.patch('/rename', ({ body }) => updateProfile(body))将生命周期转换为 "scoped" 将将生命周期导出到父实例。 而 "global" 将将生命周期导出到拥有插件的所有实例。
在 作用域 中了解更多信息。
守卫
类似于生命周期,schema 也封装到其自身实例。
我们可以指定与生命周期类似的作用域。
typescript
import { Elysia } from 'elysia'
const user = new Elysia()
.guard({
as: 'scoped',
query: t.Object({
age: t.Number(),
name: t.Optional(t.String())
}),
beforeHandle({ query: { age }, status }) {
if(age < 18) return status(403)
}
})
.get('/profile', () => 'Hi!')
.get('/settings', () => 'Settings')非常重要的一点是,每个钩子都会影响其声明之后的所有路由。
更多信息请参见 作用域。
练习
让我们为 nameCheck 和 ageCheck 定义一个作用域,使我们的应用程序正常工作。
Show answer
我们可以按如下方式修改作用域:
- 将
nameCheck作用域修改为 scoped - 将
ageCheck作用域修改为 global
typescript
import { Elysia, t } from 'elysia'
const nameCheck = new Elysia()
.onBeforeHandle(
{ as: 'scoped' },
({ query: { name }, status }) => {
if(!name) return status(401)
}
)
const ageCheck = new Elysia()
.guard({
as: 'global',
query: t.Object({
age: t.Number(),
name: t.Optional(t.String())
}),
beforeHandle({ query: { age }, status }) {
if(age < 18) return status(403)
}
})
const name = new Elysia()
.use(nameCheck)
.patch('/rename', () => 'Ok! XD')
const profile = new Elysia()
.use(ageCheck)
.use(name)
.get('/profile', () => 'Hi!')
new Elysia()
.use(profile)
.listen(3000)