API模式技能Skill api-patterns

API 模式技能用于实现安全、验证的 API 路由,包括 RLS 上下文、Zod 验证和错误处理模式。适用于后端开发中的 API 端点创建、CRUD 操作、webhook 处理和服务器端验证。关键词:API 开发、RLS、Zod 验证、Next.js、错误处理、安全 API、后端路由。

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

name: api-patterns description: 使用 RLS、Zod 验证和错误处理的 API 路由实现模式。在创建 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 路由之前:

  • [ ] 使用 Clerk 的 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

### 描述

为认证用户创建新资源。

### 身份验证

必需:Clerk 会话

### 请求体

| 字段 | 类型   | 必填 | 描述   |
| ----- | ------ | -------- | ------------- |
| 名称  | 字符串 | 是      | 资源名称 |
| 类型  | 字符串 | 否       | 资源类型 |

### 响应

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

错误(400):

{ "error": "验证失败", "details": {...} }

RLS 上下文

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


## 相关技能

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