与 Tanstack Start 集成
Elysia 可以运行在 Tanstack Start 服务器路由内。
- 创建 src/routes/api.$.ts
- 定义一个 Elysia 服务器
- 在 server.handlers 中导出 Elysia 处理器
typescript
import { Elysia } from 'elysia'
import { createFileRoute } from '@tanstack/react-router'
import { createIsomorphicFn } from '@tanstack/react-start'
const app = new Elysia({
prefix: '/api'
}).get('/', 'Hello Elysia!')
const handle = ({ request }: { request: Request }) => app.fetch(request)
export const Route = createFileRoute('/api/$')({
server: {
handlers: {
GET: handle,
POST: handle
}
}
})现在 Elysia 应该已经运行在 /api 路径下。
我们可以根据需要向 server.handlers 添加其他 HTTP 方法支持。
Eden
我们可以添加 Eden 实现类似 tRPC 的端到端类型安全。
typescript
import { Elysia } from 'elysia'
import { treaty } from '@elysiajs/eden'
import { createFileRoute } from '@tanstack/react-router'
import { createIsomorphicFn } from '@tanstack/react-start'
const app = new Elysia({
prefix: '/api'
}).get('/', 'Hello Elysia!')
const handle = ({ request }: { request: Request }) => app.fetch(request)
export const Route = createFileRoute('/api/$')({
server: {
handlers: {
GET: handle,
POST: handle
}
}
})
export const api = createIsomorphicFn()
.server(() => treaty(app).api)
.client(() => treaty<typeof app>('localhost:3000').api) 注意我们使用 createIsomorphicFn 分别为服务器和客户端创建不同的 Eden Treaty 实例。
- 服务器端直接调用 Elysia,无需 HTTP 开销。
- 客户端通过 HTTP 调用 Elysia 服务器。
在 React 组件中,可以使用 getTreaty 以类型安全的方式调用 Elysia 服务器。
加载器数据
Tanstack Start 支持 Loader,用于在渲染组件前获取数据。
tsx
import { createFileRoute } from '@tanstack/react-router'
import { getTreaty } from './api.$'
export const Route = createFileRoute('/a')({
component: App,
loader: () => getTreaty().get().then((res) => res.data)
})
function App() {
const data = Route.useLoaderData()
return data
}作为加载器调用 Elysia,会在 SSR 期间于服务器端执行,无需 HTTP 开销。
Eden Treaty 会保证服务器和客户端的类型安全。
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
}