Skip to content
在 AI 工具中打开 Anthropic

与 Nextjs 集成 ​

使用 Nextjs 应用路由,我们可以在 Nextjs 路由上运行 Elysia。

  1. 创建 app/api/[[...slugs]]/route.ts
  2. 定义一个 Elysia 服务器
  3. 导出带有所需 HTTP 方法名称的 Elysia.fetch
typescript
import { Elysia, t } from 'elysia'

const app = new Elysia({ prefix: '/api' })
    .get('/', '你好 Nextjs')
    .post('/', ({ body }) => body, {
        body: t.Object({
            name: t.String()
        })
    })

export const GET = app.fetch 
export const POST = app.fetch 

Elysia 将正常工作,因为它符合 WinterCG 规范,但如果您在 Node 环境下运行 Nextjs,某些插件(如 Elysia Static)可能不会正常工作。

您可以将 Elysia 服务器视为一个普通的 Nextjs API 路由。

通过这种方式,您可以在一个代码库中将前端和后端共同放置,并在客户端和服务器动作中拥有 Eden 的端到端类型安全。

有关更多信息,请参阅 Nextjs 路由处理程序。

pnpm ​

如果您使用 pnpm,pnpm 默认不会自动安装 peer 依赖,需要您手动安装额外依赖。

bash
pnpm add @sinclair/typebox openapi-types

前缀 ​

由于我们的 Elysia 服务器不在应用路由的根目录下,因此需要在 Elysia 服务器上标注前缀。

例如,如果您将 Elysia 服务器放在 app/user/[[...slugs]]/route.ts,需要在 Elysia 服务器上将前缀标注为 /user。

typescript
import { Elysia, t } from 'elysia'

const app = new Elysia({ prefix: '/user' }) 
	.get('/', '你好 Nextjs')
    .post('/', ({ body }) => body, {
        body: t.Object({
            name: t.String()
        })
    })

export const GET = app.fetch
export const POST = app.fetch

这样可以确保无论您将其放在哪里,Elysia 路由都能正常工作。

Eden ​

我们可以添加 Eden 来实现类似 tRPC 的端到端类型安全。

在这种方式中,我们将使用同构 fetch 模式让 Elysia 实现:

  1. 在服务端:直接调用 Elysia,无需经过网络层
  2. 在客户端:通过网络层调用 Elysia

首先需要完成以下步骤:

  1. 导出 Elysia 实例
typescript
import { Elysia } from 'elysia'

export const app = new Elysia({ prefix: '/api' }) 
	.get('/', '你好 Nextjs')
	.post(
		'/user',
		({ body }) => body,
		{
			body: treaty.schema('User', {
				name: 'string'
			})
		}
	)

export const GET = app.fetch
export const POST = app.fetch
  1. 创建 Treaty 客户端
typescript
import { treaty } from '@elysia/eden'
import type { app } from '../app/api/[[...slugs]]/route'

// .api 用以进入 /api 前缀
export const api =
  // process 在服务端和构建时定义
  typeof process !== 'undefined'
    ? treaty(app).api
    : treaty<typeof app>('localhost:3000').api

你应该使用 typeof process 而不是 typeof window,因为在构建时 window 未被定义,会导致水合错误。

  1. 在服务端和客户端组件中使用该客户端
tsx
import { api } from '../lib/eden'

export default async function Page() {
	const message = await api.get()

	return <h1>你好,{message}</h1>
}

这允许你以最小的代价实现从前端到后端的类型安全,并且适用于服务端和客户端组件,以及增量静态再生 (ISR)。

React Query ​

我们也可以使用 React Query 在客户端与 Elysia 服务器交互。

tsx
import { createFileRoute } from '@tanstack/react-router'
import { useQuery } from '@tanstack/react-query'

import { getTreaty } from './api.$'

export const Route = createFileRoute('/a')({
	component: App
})

function App() {
	const { data: response } = useQuery({ 
		queryKey: ['get'], 
		queryFn: () => getTreaty().get() 
	}) 

	return response?.data
}

这可以配合 React Query 的各种功能使用,如缓存、分页、无限查询等。


有关更多信息,请参阅 Next.js 路由处理程序。