> Discover all available pages from the documentation index: https://mastra.zisheng.pro/llms.txt # 自定义 API 路由 默认情况下,Mastra 会通过服务器自动公开已注册的 Agent 和 Workflow。要添加其他行为,可以定义自己的 HTTP 路由。 路由使用 `@mastra/core/server` 中的辅助函数 `registerApiRoute()` 提供。路由可以与 `Mastra` 实例位于同一文件中,但分开定义有助于保持配置简洁。 ```typescript import { Mastra } from '@mastra/core' import { registerApiRoute } from '@mastra/core/server' export const mastra = new Mastra({ server: { apiRoutes: [ registerApiRoute('/my-custom-route', { method: 'GET', handler: async c => { const mastra = c.get('mastra') const agent = await mastra.getAgent('my-agent') return c.json({ message: 'Custom route' }) }, }), ], }, }) ``` 注册后,可以从服务器根路径访问自定义路由。例如: ```bash curl http://localhost:4111/my-custom-route ``` 每个路由的 handler 都会接收 Hono `Context`。在 handler 中,可以访问 `Mastra` 实例以获取或调用 Agent 和 Workflow。 ## 中间件 要添加路由特定的中间件,请在调用 `registerApiRoute()` 时传递 `middleware` 数组。 ```typescript import { Mastra } from '@mastra/core' import { registerApiRoute } from '@mastra/core/server' export const mastra = new Mastra({ server: { apiRoutes: [ registerApiRoute('/my-custom-route', { method: 'GET', middleware: [ async (c, next) => { console.log(`${c.req.method} ${c.req.url}`) await next() }, ], handler: async c => { return c.json({ message: 'Custom route with middleware' }) }, }), ], }, }) ``` ## OpenAPI 文档 自定义路由可以包含 OpenAPI 元数据,以便与 Mastra 服务器路由一起显示在 Swagger UI 中。可以在 `/api/openapi.json` 访问 OpenAPI 规范,其中列出了自定义路由和内置路由。请传递包含标准 OpenAPI 操作字段的 `openapi` 选项。 ```typescript import { Mastra } from '@mastra/core' import { registerApiRoute } from '@mastra/core/server' import { z } from 'zod' export const mastra = new Mastra({ server: { apiRoutes: [ registerApiRoute('/items/:itemId', { method: 'GET', openapi: { summary: 'Get item by ID', description: 'Retrieves a single item by its unique identifier', tags: ['Items'], parameters: [ { name: 'itemId', in: 'path', required: true, description: 'The item ID', schema: { type: 'string' }, }, ], responses: { 200: { description: 'Item found', content: { 'application/json': { schema: { type: 'object', properties: { id: { type: 'string' }, name: { type: 'string' }, }, }, }, }, }, 404: { description: 'Item not found', }, }, }, handler: async c => { const itemId = c.req.param('itemId') return c.json({ id: itemId, name: 'Example Item' }) }, }), ], }, }) ``` ### 使用 Zod schema 生成 OpenAPI 文档时,`openapi` 配置中的 Zod schema 会转换为 JSON Schema: ```typescript import { Mastra } from '@mastra/core' import { registerApiRoute } from '@mastra/core/server' import { z } from 'zod' const ItemSchema = z.object({ id: z.string(), name: z.string(), price: z.number(), }) const CreateItemSchema = z.object({ name: z.string().min(1), price: z.number().positive(), }) export const mastra = new Mastra({ server: { apiRoutes: [ registerApiRoute('/items', { method: 'POST', openapi: { summary: 'Create a new item', tags: ['Items'], requestBody: { required: true, content: { 'application/json': { schema: CreateItemSchema, }, }, }, responses: { 201: { description: 'Item created', content: { 'application/json': { schema: ItemSchema, }, }, }, }, }, handler: async c => { const body = await c.req.json() return c.json({ id: 'new-id', ...body }, 201) }, }), ], }, }) ``` ### 在 Swagger UI 中查看 以开发模式(`mastra dev`)运行或在构建选项中设置 `swaggerUI: true` 时,自定义路由会显示在 `/swagger-ui` 的 Swagger UI 中。 ```typescript export const mastra = new Mastra({ server: { build: { swaggerUI: true, // Enable in production builds }, apiRoutes: [ // Your routes... ], }, }) ``` ## 身份验证 在 Mastra 服务器上配置身份验证后,自定义 API 路由默认需要身份验证。要让路由可公开访问,请设置 `requiresAuth: false`: ```typescript import { Mastra } from '@mastra/core' import { registerApiRoute } from '@mastra/core/server' import { MastraJwtAuth } from '@mastra/auth' export const mastra = new Mastra({ server: { auth: new MastraJwtAuth({ secret: process.env.MASTRA_JWT_SECRET, }), apiRoutes: [ // Protected route (default behavior) registerApiRoute('/protected-data', { method: 'GET', handler: async c => { // Access authenticated user from request context const user = c.get('requestContext').get('user') return c.json({ message: 'Authenticated user', user }) }, }), // Public route (no authentication required) registerApiRoute('/webhooks/github', { method: 'POST', requiresAuth: false, // Explicitly opt out of authentication handler: async c => { const payload = await c.req.json() // Process webhook without authentication return c.json({ received: true }) }, }), ], }, }) ``` ### 身份验证 behavior - **未配置身份验证**:所有路由(内置和自定义)均为公开路由 - **已配置身份验证**: - Mastra 提供的路由(`/api/agents/*`、`/api/workflows/*` 等)需要身份验证 - 自定义路由默认需要身份验证 - 自定义路由可以使用 `requiresAuth: false` 选择退出身份验证 ### 访问用户信息 请求通过身份验证后,可以在请求上下文中访问用户对象: ```typescript registerApiRoute('/user-profile', { method: 'GET', handler: async c => { const requestContext = c.get('requestContext') const user = requestContext.get('user') return c.json({ user }) }, }) ``` 有关身份验证 Provider 的更多信息,请参阅[身份验证文档](https://mastra.zisheng.pro/docs/server/auth)。 ## 客户端断开连接后继续生成 [`chatRoute()`](https://mastra.zisheng.pro/reference/ai-sdk/chat-route) 等内置流式辅助函数会将传入请求的 `AbortSignal` 转发给 `agent.stream()`。当浏览器断开连接应取消模型调用时,这是合适的默认行为。 对于应在客户端断开连接时停止的自定义流式路由,请将 `c.req.raw.signal` 传递给 `agent.stream()` 等长期运行的工作。客户端连接关闭时,Mastra 基于 Node 的 Adapter 也会停止读取自定义路由的流式 `Response` 正文。并非由客户端断开连接引起的流式响应正文错误,仍会通过 Adapter 的常规错误处理传播。在 Hono 中,断开连接行为取决于宿主运行时是否将连接关闭事件转发到 `request.signal`。 ```typescript registerApiRoute('/stream', { method: 'GET', handler: async c => { const stream = await agent.stream(prompt, { abortSignal: c.req.raw.signal, }) return stream.toTextStreamResponse() }, }) ``` 如果希望服务器在客户端断开连接后仍继续生成并持久化最终响应,请围绕底层 `MastraModelOutput` 构建自定义路由。启动 Agent 流时不要转发 `c.req.raw.signal`,然后在后台调用 `consumeStream()`,使生成过程在服务器端继续。 ```typescript import { createUIMessageStream, createUIMessageStreamResponse, InferUIMessageChunk, UIMessage, } from 'ai' import { toAISdkStream } from '@mastra/ai-sdk' import { Mastra } from '@mastra/core' import { registerApiRoute } from '@mastra/core/server' export const mastra = new Mastra({ server: { apiRoutes: [ registerApiRoute('/chat/persist/:agentId', { method: 'POST', handler: async c => { const { messages, memory } = await c.req.json() const mastra = c.get('mastra') const agent = mastra.getAgent(c.req.param('agentId')) const stream = await agent.stream(messages, { memory, // Do not pass c.req.raw.signal if this route should keep running // after the client disconnects. }) void stream.consumeStream().catch(error => { mastra.getLogger()?.error('Background stream consumption failed', { error }) }) const uiStream = createUIMessageStream({ originalMessages: messages, execute: async ({ writer }) => { for await (const part of toAISdkStream(stream, { from: 'agent' })) { writer.write(part as InferUIMessageChunk) } }, }) return createUIMessageStreamResponse({ stream: uiStream }) }, }), ], }, }) ``` > **备注:** 仅当明确希望 HTTP 客户端离开后工作仍继续时,才使用此模式。如果希望断开连接时取消生成,请继续使用 `chatRoute()`,或自行转发请求的 `AbortSignal`。 ## 相关内容 - [registerApiRoute() 参考](https://mastra.zisheng.pro/reference/server/register-api-route):完整 API 参考 - [服务器中间件](https://mastra.zisheng.pro/docs/server/middleware):全局中间件配置 - [Mastra 服务器](https://mastra.zisheng.pro/docs/server/mastra-server):服务器配置选项