You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js应用中从Hono API端点实现类型安全的数据获取?

在Next.js中实现跨子域名访问Hono API的类型安全数据获取

1. 在Hono API端导出类型并配置CORS

首先在你的Hono+Bun API项目中,定义路由并导出API的类型,同时配置CORS允许Next.js子域名访问:

// api/src/index.ts
import { Hono } from 'hono'
import { cors } from 'hono/cors'

const app = new Hono()

// 配置CORS,允许portal.example.com跨域访问
app.use('*', cors({
  origin: 'https://portal.example.com',
  credentials: true // 需要传递Cookie/认证信息时开启
}))

// 定义API路由
app.get('/api/users', (c) => {
  return c.json({
    id: 1,
    name: 'John Doe',
    email: 'john@example.com'
  })
})

app.post('/api/users', async (c) => {
  const body = await c.req.json<{ name: string; email: string }>()
  return c.json({ id: Date.now(), ...body }, 201)
})

// 导出API的完整类型(替代找不到的AppType)
export type ApiType = typeof app

export default app

2. 共享API类型到Next.js项目

将Hono项目中导出的ApiType共享给Next.js项目,推荐三种方式:

  • 本地链接:用Bun/npm的link命令将API项目作为本地依赖关联到Next.js项目
  • 共享类型文件:将类型单独抽成文件,复制到Next.js项目或通过Git Submodule管理
  • 私有npm包:将API类型发布到私有仓库,Next.js项目安装依赖

示例假设两个项目在同一目录下,直接通过相对路径导入类型:

项目结构
├── api/          # Hono+Bun API项目
│   └── src/
│       └── index.ts
└── nextjs/       # Next.js项目
    └── app/
        ├── lib/
        │   └── api-client.ts
        └── page.tsx

3. 在Next.js中创建类型安全的API客户端

使用Hono的createClient工具生成类型安全的客户端,自动关联API路由和返回类型:

// nextjs/app/lib/api-client.ts
import { createClient } from 'hono/client'
// 导入Hono API导出的类型
import type { ApiType } from '../../../api/src/index'

// 创建客户端,指定API基础域名
const apiClient = createClient<ApiType>({
  baseURL: 'https://api.example.com'
})

// 封装业务API调用函数
export const api = {
  getUser: async () => {
    const res = await apiClient.api.users.$get()
    if (!res.ok) throw new Error('获取用户失败')
    return res.json()
  },
  createUser: async (userData: { name: string; email: string }) => {
    const res = await apiClient.api.users.$post({ json: userData })
    if (!res.ok) throw new Error('创建用户失败')
    return res.json()
  }
}

4. 在Next.js组件中使用类型安全的API调用

Server Component 示例

// nextjs/app/page.tsx
import { api } from './lib/api-client'

export default async function Home() {
  // Server Component中直接调用API
  const user = await api.getUser()

  return (
    <div className="container">
      <h1>当前用户:{user.name}</h1>
      <p>邮箱:{user.email}</p>
    </div>
  )
}

Client Component 示例

// nextjs/app/components/CreateUser.tsx
'use client'

import { useState } from 'react'
import { api } from '../lib/api-client'

export default function CreateUser() {
  const [name, setName] = useState('')
  const [email, setEmail] = useState('')

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    try {
      const newUser = await api.createUser({ name, email })
      alert(`用户创建成功:${newUser.name}`)
    } catch (err) {
      alert((err as Error).message)
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="姓名"
        required
      />
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="邮箱"
        required
      />
      <button type="submit">创建用户</button>
    </form>
  )
}

关键说明

  • 替代AppType:新版Hono已不再使用AppType,直接通过typeof app导出API的完整类型即可
  • 跨域保障:必须在Hono端配置CORS指定允许的Next.js子域名,否则浏览器会拦截跨域请求
  • 版本一致性:确保Next.js和Hono项目使用相同版本的Hono依赖,避免类型不兼容

内容的提问来源于stack exchange,提问作者hantoren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 05:49:56