MuseMVP 文档
API 接口

定义新路由

创建新 API 端点、校验与 OpenAPI 元数据的逐步指南。

本指南介绍如何在 MuseMVP 中添加新的 API 路由,遵循现有的校验、中间件与 OpenAPI 文档模式。

逐步流程

src/backend/database/ 中添加或更新数据库 schema 与 query 函数。

src/backend/api/routes/ 中创建新 Hono 路由或扩展现有路由。

src/backend/api/app.ts 中注册路由。

src/backend/api-client/ 中添加 API client hooks 供前端使用。


1. 定义路由处理器

创建新路由文件或扩展现有文件。使用 Zod 做校验,describeRoute 做 OpenAPI 元数据。

// src/backend/api/routes/example/router.ts
import { Hono } from "hono";
import { describeRoute, resolver, validator } from "hono-openapi";
import { z } from "zod";
import { authMiddleware } from "@/backend/api/middleware/auth";

const querySchema = z.object({
  limit: z.string().optional().default("10").transform(Number),
  offset: z.string().optional().default("0").transform(Number),
});

const responseSchema = z.object({
  items: z.array(z.object({ id: z.string(), name: z.string() })),
  total: z.number(),
});

export const exampleRouter = new Hono()
  .basePath("/example")
  .use(authMiddleware)
  .get(
    "/",
    validator("query", querySchema),
    describeRoute({
      tags: ["Example"],
      summary: "List items",
      responses: {
        200: {
          description: "Items returned",
          content: {
            "application/json": {
              schema: resolver(responseSchema),
            },
          },
        },
      },
    }),
    async (c) => {
      const { limit, offset } = c.req.valid("query");
      const user = c.get("user");
      // 调用 query 层...
      return c.json({ items: [], total: 0 });
    },
  );

2. 注册路由

src/backend/api/app.ts 中添加新路由:

import { exampleRouter } from "./routes/example/router";

const appRouter = app
  .route("/", authRouter)
  .route("/", exampleRouter)  // 添加此行
  // ... 其他路由

3. 校验模式

位置用途示例
validator("query", schema)查询参数分页、搜索
validator("json", schema)JSON 请求体创建/更新 payload
validator("form", schema)表单数据联系表单、文件上传
validator("param", schema)路径参数/conversations/:id

4. 中间件选项

中间件使用场景
authMiddleware需要已登录用户;设置 c.get("user")c.get("session")
adminMiddleware需要 admin 角色;用于仅管理员端点
localeMiddleware从请求/cookie 设置 c.get("locale") 用于 i18n

5. API Client Hook

创建调用新端点的 TanStack Query hook:

// src/backend/api-client/example/use-example.ts
import { useQuery } from "@tanstack/react-query";
import { apiClient } from "@/backend/api-client/api-client";

export function useExample(params?: { limit?: number; offset?: number }) {
  return useQuery({
    queryKey: ["example", params],
    queryFn: async () => {
      const res = await apiClient.example.$get({ query: params });
      if (!res.ok) throw new Error("Fetch failed");
      return res.json();
    },
  });
}

参考实现

src/backend/api/routes/admin/users.ts
src/backend/api/routes/contact/router.ts
src/backend/api/routes/aichat/router.ts
  • 管理路由admin/users.tsadminMiddleware、query 校验、describeRoute
  • 公开路由contact/router.tslocaleMiddleware、表单校验
  • 鉴权路由aichat/router.tsauthMiddleware、param + json 校验