API模式技能Skill api-patterns

API模式技能是一个用于实现安全、验证的API路由的开发模式集合,包括RLS上下文管理、Zod验证和结构化错误处理。关键词:API开发、后端开发、安全验证、错误处理、RLS、Zod。

后端开发 0 次安装 0 次浏览 更新于 3/15/2026

name: api-patterns description: API路由实现模式,包含RLS、Zod验证和错误处理。在创建API路由、实现端点或添加服务器端验证时使用。

API模式技能

目的

引用现有API模式并提供安全、验证的API路由实现的检查表。所有API路由必须使用RLS上下文助手——参见rls-patterns技能。

适用场景

  • 创建新API路由
  • 实现CRUD端点
  • 添加请求/响应验证
  • 处理webhooks
  • 实现错误处理模式

权威参考(必读)

模式 位置 目的
用户上下文API docs/patterns/api/user-context-api.md 用户范围操作
管理员上下文API docs/patterns/api/admin-context-api.md 管理员范围操作
Zod验证 docs/patterns/api/zod-validation-api.md 请求/响应验证
Webhook处理器 docs/patterns/api/webhook-handler.md Webhook处理
奖励内容 docs/patterns/api/bonus-content-delivery.md 受保护内容交付

停止条件

禁止模式

// 禁止:直接调用Prisma(绕过RLS)
const users = await prisma.user.findMany();
// 必须使用:withUserContext、withAdminContext或withSystemContext

// 禁止:缺少身份验证检查
export async function GET(req: Request) {
  return getUserData(); // 没有身份验证检查!
}

// 禁止:未验证的用户输入
const { userId } = await req.json();
// 必须使用Zod模式验证

// 禁止:通用错误响应
return new Response("错误", { status: 500 });
// 必须使用结构化错误响应

正确模式

// 正确:RLS上下文 + 身份验证检查
export async function GET(req: Request) {
  const { userId } = await auth();
  if (!userId) {
    return NextResponse.json({ error: "未授权" }, { status: 401 });
  }

  const data = await withUserContext(prisma, userId, async (client) => {
    return client.user.findUnique({ where: { user_id: userId } });
  });

  return NextResponse.json(data);
}

// 正确:Zod验证
const schema = z.object({
  email: z.string().email(),
  name: z.string().min(1),
});

const result = schema.safeParse(body);
if (!result.success) {
  return NextResponse.json(
    { error: "验证失败", details: result.error.flatten() },
    { status: 400 },
  );
}

API路由检查表

在任何API路由之前:

  • [ ] 使用身份验证提供者的await auth()进行身份验证检查
  • [ ] 为未认证用户提供适当的401响应
  • [ ] 使用Zod模式进行请求验证
  • [ ] RLS上下文包装器(withUserContext/withAdminContext/withSystemContext
  • [ ] 结构化错误响应,状态码适当
  • [ ] 请求/响应的TypeScript类型

标准响应模式

成功响应

return NextResponse.json({ data, success: true }, { status: 200 });

错误响应

return NextResponse.json(
  {
    error: "人类可读的错误消息",
    code: "ERROR_CODE",
    details: optional_details,
  },
  { status: 400 | 401 | 403 | 404 | 500 },
);

状态码

代码 何时使用
200 成功
201 创建(POST)
400 错误请求 / 验证错误
401 未认证
403 禁止(已认证但未授权)
404 资源未找到
500 服务器错误

API路由模板

import { auth } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
import { z } from "zod";
import { withUserContext } from "@/lib/rls-helpers";
import { prisma } from "@/lib/prisma";

// 请求验证模式
const RequestSchema = z.object({
  // 定义期望字段
});

export async function POST(req: Request) {
  try {
    // 1. 身份验证
    const { userId } = await auth();
    if (!userId) {
      return NextResponse.json({ error: "未授权" }, { status: 401 });
    }

    // 2. 解析和验证请求
    const body = await req.json();
    const result = RequestSchema.safeParse(body);
    if (!result.success) {
      return NextResponse.json(
        { error: "验证失败", details: result.error.flatten() },
        { status: 400 },
      );
    }

    // 3. 使用RLS上下文执行
    const data = await withUserContext(prisma, userId, async (client) => {
      return client.resource.create({ data: result.data });
    });

    // 4. 返回成功响应
    return NextResponse.json({ data, success: true }, { status: 201 });
  } catch (error) {
    console.error("API错误:", error);
    return NextResponse.json(
      { error: "内部服务器错误" },
      { status: 500 },
    );
  }
}

API文档模板

用于记录新端点:

## 端点:POST /api/resource

### 描述

为认证用户创建新资源。

### 认证

必需:会话认证

### 请求体

| 字段 | 类型   | 必需 | 描述       |
| ---- | ------ | ---- | ---------- |
| name  | string | 是  | 资源名称   |
| type  | string | 否  | 资源类型   |

### 响应

**成功(201)**:
\`\`\`json
{ "data": { "id": 1, "name": "..." }, "success": true }
\`\`\`

**错误(400)**:
\`\`\`json
{ "error": "验证失败", "details": {...} }
\`\`\`

### RLS上下文

使用`withUserContext` - 用户只能访问自己的资源。

相关技能

  • rls-patterns: RLS上下文助手使用(所有数据库操作必需)
  • security-audit: API安全验证
  • testing-patterns: API端点测试