Skip to content
Our Sponsors
Open in Anthropic

title: Guard - Elysia 教程 layout: false search: false authors: [] head: - - meta - property: 'og:title' content: Guard - Elysia 教程

- - meta
  - name: 'description'
    content: Elysia 提供了一个 guard 方法,可以一次性向多个路由批量添加钩子和模式。

- - meta
  - property: 'og:description'
    content: Elysia 提供了一个 guard 方法,可以一次性向多个路由批量添加钩子和模式。

Guard

当你需要向应用程序应用多个钩子时,不必重复多次添加钩子,你可以使用 guard 来批量向应用程序添加钩子。

typescript
import { Elysia, t } from 'elysia'

new Elysia()
	.onBeforeHandle(({ query: { name }, status }) => { 
		if(!name) return status(401) 
	}) 
	.onBeforeHandle(({ query: { name } }) => { 
		console.log(name) 
	}) 
	.onAfterResponse(({ responseValue }) => { 
		console.log(responseValue) 
	}) 
	.guard({ 
		beforeHandle: [ 
			({ query: { name }, status }) => { 
				if(!name) return status(401) 
			}, 
			({ query: { name } }) => { 
				console.log(name) 
			} 
		], 
		afterResponse({ responseValue }) { 
			console.log(responseValue) 
		} 
	}) 
	.get(
		'/auth',
		({ query: { name = 'anon' } }) => `你好 ${name}!`,
		{
			query: t.Object({
				name: t.String()
			})
		}
	)
	.get(
		'/profile',
		({ query: { name = 'anon' } }) => `你好 ${name}!`,
		{
			query: t.Object({
				name: t.String()
			})
		}
	)
	.listen(3000)

不仅如此,你还可以使用 guard模式应用到多个路由。

typescript
import { Elysia, t } from 'elysia'

new Elysia()
	.guard({
		beforeHandle: [
			({ query: { name }, status }) => {
				if(!name) return status(401)
			},
			({ query: { name } }) => {
				console.log(name)
			}
		],
		afterResponse({ responseValue }) {
			console.log(responseValue)
		},
		query: t.Object({ 
			name: t.String() 
		}) 
	})
	.get(
		'/auth',
		({ query: { name = 'anon' } }) => `你好 ${name}!`,
		{ 
			query: t.Object({ 
				name: t.String() 
			}) 
		} 
	)
	.get(
		'/profile',
		({ query: { name = 'anon' } }) => `你好 ${name}!`,
		{ 
			query: t.Object({ 
				name: t.String() 
			}) 
		} 
	)
	.listen(3000)

这将会将钩子和模式应用到在同一实例中调用 .guard 之后的每个路由。

更多信息请参阅 Guard

练习

让我们将两种类型的钩子付诸实践。

  1. Authentication

    Let's add a simple authentication middleware to GET "/auth" endpoint using beforeHandle hook. If query `name` is provided, we will let the request pass, otherwise we will return 401 status.

  2. Interceptor Hook

    Now, let's create another endpoint GET "/profile" that has the same logic with authentication. We can refactor our code by using interceptor hook to avoid duplication.

Show answer

我们可以使用 beforeHandle 在请求到达处理器之前拦截它,并使用 status 方法返回响应。

typescript
import { Elysia } from 'elysia'

new Elysia()
	.onBeforeHandle(({ query: { name }, status }) => {
		if(!name) return status(401)
	})
	.get('/auth', ({ query: { name = 'anon' } }) => {
		return `你好 ${name}!`
	})
	.get('/profile', ({ query: { name = 'anon' } }) => {
		return `你好 ${name}!`
	})
	.listen(3000)
  • index.ts