> ## Documentation Index
> Fetch the complete documentation index at: https://codofly.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# API 开发

> 学习如何在 Codofly Template 中创建和管理 API 端点

# API 开发

本文档将指导您如何在 Codofly Template 中创建 API 端点。

## API Routes 基础

### 目录结构

```
app/api/
├── users/
│   ├── route.ts            # GET/POST /api/users
│   └── [id]/
│       └── route.ts        # GET/PUT/DELETE /api/users/[id]
├── chats/
│   └── route.ts            # GET/POST /api/chats
└── auth/
    └── login/
        └── route.ts        # POST /api/auth/login
```

<Callout type="info">
  只有 `route.ts` 文件会创建 API 端点，每个 HTTP 方法对应一个导出函数。
</Callout>

## 创建 API 端点

### 基础示例

```typescript title="app/api/users/route.ts" theme={null}
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'

// GET /api/users
export async function GET() {
  const users = await prisma.user.findMany()
  return NextResponse.json({ data: users })
}

// POST /api/users
export async function POST(request: NextRequest) {
  const body = await request.json()
  const user = await prisma.user.create({ data: body })
  return NextResponse.json({ data: user }, { status: 201 })
}
```

### 动态路由

```typescript title="app/api/users/[id]/route.ts" theme={null}
export async function GET(
  request: NextRequest,
  { params }: { params: { id: string } }
) {
  const user = await prisma.user.findUnique({
    where: { id: params.id }
  })
  
  if (!user) {
    return NextResponse.json({ error: '用户未找到' }, { status: 404 })
  }
  
  return NextResponse.json({ data: user })
}

export async function PUT(
  request: NextRequest,
  { params }: { params: { id: string } }
) {
  const body = await request.json()
  const user = await prisma.user.update({
    where: { id: params.id },
    data: body
  })
  return NextResponse.json({ data: user })
}

export async function DELETE(
  request: NextRequest,
  { params }: { params: { id: string } }
) {
  await prisma.user.delete({ where: { id: params.id } })
  return NextResponse.json({ success: true })
}
```

## 数据库操作

### Prisma 基础用法

```typescript title="lib/db-operations.ts" theme={null}
import { prisma } from '@/lib/prisma'

// 查询操作
export async function getUsers() {
  return await prisma.user.findMany({
    include: { chats: true }
  })
}

// 创建操作
export async function createUser(data: any) {
  return await prisma.user.create({
    data: {
      email: data.email,
      name: data.name
    }
  })
}

// 更新操作
export async function updateUser(id: string, data: any) {
  return await prisma.user.update({
    where: { id },
    data
  })
}
```

## 认证中间件

### 保护 API 路由

```typescript title="lib/auth-middleware.ts" theme={null}
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import { NextRequest, NextResponse } from 'next/server'

export async function withAuth(handler: Function) {
  return async (request: NextRequest, context: any) => {
    const session = await getServerSession(authOptions)
    
    if (!session) {
      return NextResponse.json(
        { error: '未授权访问' },
        { status: 401 }
      )
    }

    return handler(request, context)
  }
}
```

### 使用认证中间件

```typescript title="app/api/protected/route.ts" theme={null}
import { withAuth } from '@/lib/auth-middleware'

export const GET = withAuth(async (request: NextRequest) => {
  // 需要认证的 API 逻辑
  return NextResponse.json({ message: '受保护的内容' })
})
```

## 错误处理

### 统一错误响应

```typescript title="lib/api-response.ts" theme={null}
import { NextResponse } from 'next/server'

export function successResponse(data: any, status = 200) {
  return NextResponse.json({
    success: true,
    data
  }, { status })
}

export function errorResponse(message: string, status = 500) {
  return NextResponse.json({
    success: false,
    error: message
  }, { status })
}
```

### 错误处理示例

```typescript title="app/api/users/route.ts" theme={null}
import { successResponse, errorResponse } from '@/lib/api-response'

export async function GET() {
  try {
    const users = await prisma.user.findMany()
    return successResponse(users)
  } catch (error) {
    console.error('获取用户失败:', error)
    return errorResponse('服务器错误')
  }
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    
    // 验证数据
    if (!body.email || !body.name) {
      return errorResponse('邮箱和姓名为必填项', 400)
    }

    const user = await prisma.user.create({ data: body })
    return successResponse(user, 201)
  } catch (error) {
    if (error.code === 'P2002') {
      return errorResponse('邮箱已存在', 409)
    }
    return errorResponse('创建用户失败')
  }
}
```

## 常见场景

### 聊天 API 示例

```typescript title="app/api/chats/route.ts" theme={null}
export async function GET(request: NextRequest) {
  const session = await getServerSession(authOptions)
  
  const chats = await prisma.chat.findMany({
    where: { userId: session.user.id },
    include: { messages: true },
    orderBy: { updatedAt: 'desc' }
  })
  
  return successResponse(chats)
}

export async function POST(request: NextRequest) {
  const session = await getServerSession(authOptions)
  const { title } = await request.json()
  
  const chat = await prisma.chat.create({
    data: {
      title,
      userId: session.user.id
    }
  })
  
  return successResponse(chat, 201)
}
```

### 文件上传

```typescript title="app/api/upload/route.ts" theme={null}
export async function POST(request: NextRequest) {
  const formData = await request.formData()
  const file = formData.get('file') as File
  
  if (!file) {
    return errorResponse('未找到文件', 400)
  }
  
  // 保存文件逻辑
  const buffer = Buffer.from(await file.arrayBuffer())
  const filename = `${Date.now()}-${file.name}`
  
  // 返回文件URL
  return successResponse({ 
    url: `/uploads/${filename}`,
    filename 
  })
}
```

## 最佳实践

1. **使用 TypeScript** 确保类型安全
2. **统一响应格式** 便于前端处理
3. **添加错误处理** 提供有意义的错误信息
4. **验证输入数据** 防止无效数据
5. **使用中间件** 处理认证和权限

<Note>
  查看 [数据库功能](/features/database) 了解更多 Prisma 使用方法。
</Note>
