扩展上下文
Elysia 提供了一个带有小型实用工具的上下文,帮助您入门。
您可以通过以下方式扩展 Elysia 的上下文:
Decorate
单例,且不可变,在所有请求之间共享。
typescript
import { Elysia } from 'elysia'
class Logger {
log(value: string) {
console.log(value)
}
}
new Elysia()
.decorate('logger', new Logger())
.get('/', ({ logger }) => {
logger.log('hi')
return 'hi'
})装饰值将作为只读属性在上下文中可用,请参阅 Decorate。
State
一个在所有请求之间共享的可变引用。
typescript
import { Elysia } from 'elysia'
new Elysia()
.state('count', 0)
.get('/', ({ store }) => {
store.count++
return store.count
})状态将在 context.store 中可用,它在每个请求之间共享,请参阅 State。
Resolve / Derive
Decorate 值被注册为单例。而 Resolve 和 Derive 允许您按请求抽象上下文值。
typescript
import { Elysia } from 'elysia'
new Elysia()
.derive(({ headers: { authorization } }) => ({
authorization
}))
.get('/', ({ authorization }) => authorization)任何返回值都将在上下文中可用,但 status 除外,它将直接发送给客户端,并中止后续的处理程序。
resolve 和 derive 的语法类似,但它们有不同的用例。在底层,两者都是生命周期的语法糖(带有类型安全):
由于 derive 基于 transform,意味着数据尚未经过验证和强制转换/转换。如果您需要经过验证的数据,最好使用 resolve。
作用域
State 和 Decorate 在所有请求和实例之间共享。Resolve 和 Derive 是按请求的,并且具有封装作用域(因为它们基于生命周期事件)。
如果您想使用来自插件的解析/派生值,则必须声明一个 Scope。
typescript
import { Elysia } from 'elysia'
const plugin = new Elysia()
.derive(
{ as: 'scoped' },
({ headers: { authorization } }) => ({
authorization
})
)
new Elysia()
.use(plugin)
.get('/', ({ authorization }) => authorization)
.listen(3000)练习
让我们尝试扩展 Elysia 的上下文。
Show answer
我们可以使用 resolve 从查询中提取 age。
typescript
import { Elysia, t } from 'elysia'
class Logger {
log(info: string) {
console.log(info)
}
}
new Elysia()
.decorate('logger', new Logger())
.onRequest(({ request, logger }) => {
logger.log(`Request to ${request.url}`)
})
.guard({
query: t.Optional(
t.Object({
age: t.Number({ min: 15 })
})
)
})
.resolve(({ query: { age }, status }) => {
if(!age) return status(401)
return { age }
})
.get('/profile', ({ age }) => age)
.listen(3000)