Reading time: ~17 min
Preview
Live PreviewPagePreview Mode
api develop
By Admin
Published August 26, 2025
0 views
API开发与使用标准
🏗️ API架构原则
完整的API架构
Frontend → 统一API客户端 → API Routes → Services → Repositories → DAOs → Database
目录结构
- API路由:
app/api/
- Next.js API路由 - 服务端服务:
lib/services/server/
- 服务端业务逻辑 - 客户端服务:
lib/services/client/
- 客户端业务逻辑 - API客户端:
lib/api/
- 统一API调用层 - 类型定义:
lib/api/types/
- API相关类型
📋 API类型定义约束
🚫 严格禁止的做法
1. 禁止在Service文件中定义API类型
❌ 绝对禁止在lib/services/client/
或lib/services/server/
中定义API响应类型:
// ❌ 错误:不要在service文件中定义API类型 // lib/services/client/order.service.ts export interface OrderDetailsResponse { // 🚫 禁止 id: string; status: string; // ... }
2. 禁止页面组件直接导入Service类型
❌ 绝对禁止页面组件直接从service文件导入类型:
// ❌ 错误:页面组件不应该直接导入service类型 import { OrderDetailsResponse } from '@/lib/services/client/order.service';
3. 禁止API类型定义分散
❌ 绝对禁止在多个地方重复定义相同的API类型:
// ❌ 错误:不要在多个地方定义ApiResponse // lib/api/types.ts export interface ApiResponse<T> { ... } // lib/services/client/order.service.ts export interface ApiResponse<T> { ... } // 🚫 重复定义
✅ 正确的类型定义层次结构
1. 核心层次结构
types/
├── core/ # 核心业务类型(数据库映射后的业务对象)
│ ├── order.ts # Order, OrderStatus, OrderItem等
│ ├── user.ts # User, UserProfile, UserRole等
│ ├── product.ts # Product, ProductType, ProductSpec等
│ ├── payment.ts # Payment, PaymentStatus, PaymentMethod等
│ └── common.ts # 通用类型和工具类型
│
├── api/ # API专用类型(请求/响应)
│ ├── requests/ # API请求类型
│ │ ├── order.ts # CreateOrderRequest, UpdateOrderRequest等
│ │ ├── user.ts # CreateUserRequest, UpdateProfileRequest等
│ │ └── common.ts # 通用请求类型
│ │
│ ├── responses/ # API响应类型
│ │ ├── order.ts # OrderDetailsResponse, OrderListResponse等
│ │ ├── user.ts # UserProfileResponse, UserOrdersResponse等
│ │ └── common.ts # ApiResponse, PaginatedResponse等
│ │
│ └── index.ts # 统一导出
│
├── database/ # 数据库类型(Supabase生成+映射器)
└── index.ts # 全局类型导出
2. API类型定义规则
A. 请求类型定义
// types/api/requests/order.ts import { ProductType, Address } from '../../core'; export interface CreateOrderRequest { customerInfo: { email: string; phone: string; name?: string; }; items: OrderItemRequest[]; shippingAddress: Address; billingAddress?: Address; notes?: string; } export interface UpdateOrderRequest { phone?: string; shippingAddress?: Address; notes?: string; } export interface OrderListRequest { page?: number; pageSize?: number; status?: string; search?: string; sortBy?: string; sortOrder?: 'asc' | 'desc'; }
B. 响应类型定义
// types/api/responses/order.ts import { Order, OrderStatus, ProductType } from '../../core'; export interface OrderDetailsResponse { id: string; orderNumber: string; userId: string; status: OrderStatus; items: OrderItemResponse[]; shippingAddress: AddressResponse; billingAddress?: AddressResponse; pricing: PricingResponse; deliveryInfo: DeliveryResponse; physicalInfo?: PhysicalResponse; createdAt: string; updatedAt: string; } export interface OrderListResponse { orders: OrderDetailsResponse[]; pagination: PaginationResponse; } export interface OrderStatsResponse { totalOrders: number; totalAmount: number; statusBreakdown: { status: OrderStatus; count: number; }[]; }
C. 通用响应类型
// types/api/responses/common.ts export interface ApiResponse<T = unknown> { success: boolean; data?: T; error?: string; message?: string; code?: string; timestamp?: string; requestId?: string; } export interface PaginatedResponse<T> { data: T[]; pagination: { page: number; pageSize: number; total: number; totalPages: number; hasNextPage: boolean; hasPreviousPage: boolean; }; } export interface OperationResponse { success: boolean; message?: string; affectedRows?: number; }
3. 统一导出规范
A. API类型统一导出
// types/api/index.ts // 请求类型 export * from './requests/order'; export * from './requests/user'; export * from './requests/common'; // 响应类型 export * from './responses/order'; export * from './responses/user'; export * from './responses/common'; // 类型别名(便于使用) export type { CreateOrderRequest, UpdateOrderRequest, OrderDetailsResponse, OrderListResponse, ApiResponse, PaginatedResponse } from './requests/order';
B. 全局类型导出
// types/index.ts // 核心业务类型 export * from './core'; // API类型 export * from './api'; // 数据库类型(仅服务端使用) export type * from './database';
4. 页面组件导入规范
✅ 正确的导入方式
// app/profile/orders/[id]/components/OrderDetails.tsx import type { OrderDetailsResponse, ApiResponse } from '@/types/api'; // 或者使用统一导出 import type { OrderDetailsResponse, ApiResponse } from '@/types'; interface OrderDetailsProps { order: OrderDetailsResponse; }
5. 服务层类型使用规范
A. 客户端服务
// lib/services/client/order.service.ts import { API } from '@/lib/api/client'; import type { CreateOrderRequest, UpdateOrderRequest, OrderDetailsResponse, OrderListResponse, ApiResponse } from '@/types/api'; export async function createOrder( request: CreateOrderRequest ): Promise<ApiResponse<OrderDetailsResponse>> { return await API.order.create<OrderDetailsResponse>(request); } export async function getOrderDetails( orderId: string ): Promise<ApiResponse<OrderDetailsResponse>> { return await API.order.getDetails<OrderDetailsResponse>(orderId); }
B. 服务端服务
// lib/services/server/order.service.ts import type { CreateOrderRequest, OrderDetailsResponse, OrderListResponse } from '@/types/api'; import type { Order } from '@/types/core'; export class OrderService { async createOrder(request: CreateOrderRequest): Promise<OrderDetailsResponse> { // 业务逻辑 const order = await this.orderRepository.create(request); return this.mapOrderToResponse(order); } private mapOrderToResponse(order: Order): OrderDetailsResponse { // 映射逻辑 return { id: order.id, orderNumber: order.orderNumber, // ...其他字段映射 }; } }
6. API路由类型使用规范
// app/api/order/create/route.ts import { NextRequest, NextResponse } from 'next/server'; import type { CreateOrderRequest, OrderDetailsResponse, ApiResponse } from '@/types/api'; export async function POST(request: NextRequest) { try { const body: CreateOrderRequest = await request.json(); const orderService = new OrderService(); const orderResponse = await orderService.createOrder(body); const response: ApiResponse<OrderDetailsResponse> = { success: true, data: orderResponse, timestamp: new Date().toISOString() }; return NextResponse.json(response); } catch (error) { const errorResponse: ApiResponse<never> = { success: false, error: error instanceof Error ? error.message : 'Unknown error' }; return NextResponse.json(errorResponse, { status: 500 }); } }
🔧 类型定义最佳实践
1. 命名约定
- 请求类型:
{Resource}{Action}Request
(如CreateOrderRequest
) - 响应类型:
{Resource}{Action}Response
(如OrderDetailsResponse
) - 列表响应:
{Resource}ListResponse
(如OrderListResponse
) - 统计响应:
{Resource}StatsResponse
(如OrderStatsResponse
)
2. 类型继承和组合
// ✅ 正确:使用继承和组合 export interface BaseRequest { requestId?: string; timestamp?: string; } export interface CreateOrderRequest extends BaseRequest { customerInfo: CustomerInfo; items: OrderItemRequest[]; } export interface UpdateOrderRequest extends BaseRequest { orderId: string; updates: Partial<CreateOrderRequest>; }
3. 泛型约束
// ✅ 正确:使用泛型约束 export interface PaginatedRequest<T = Record<string, unknown>> { page?: number; pageSize?: number; filters?: T; sortBy?: keyof T; sortOrder?: 'asc' | 'desc'; } export interface OrderListRequest extends PaginatedRequest<{ status?: OrderStatus; dateRange?: { start: string; end: string }; minAmount?: number; maxAmount?: number; }> {}
🖥️ 服务端API开发规范
API路由组织
app/api/
├── auth/ # 认证相关
├── quote/ # 报价相关
│ ├── calculate/ # 报价计算
│ ├── submit/ # 提交报价
│ └── [id]/ # 具体报价操作
├── admin/ # 管理员功能
├── payment/ # 支付相关
└── user/ # 用户相关
标准API路由结构
// ✅ 正确:标准API路由结构 import { NextRequest, NextResponse } from 'next/server'; import { createClient } from '@/utils/supabase/server'; export async function POST(request: NextRequest) { try { // 1. 认证检查 const supabase = createClient(); const { data: { user } } = await supabase.auth.getUser(); if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } // 2. 数据验证 const body = await request.json(); const validatedData = validateRequestData(body); // 3. 业务逻辑(通过Service层) const service = new OrderService(); const result = await service.processOrder(validatedData); // 4. 返回统一格式 return NextResponse.json({ success: true, data: result }); } catch (error) { return NextResponse.json({ success: false, error: error instanceof Error ? error.message : 'Internal server error' }, { status: 500 }); } }
服务层实现
// ✅ 正确:服务层实现 export class QuoteService { constructor(private supabase: SupabaseClient) {} async calculateQuote(data: QuoteCalculationRequest): Promise<QuoteCalculationResult> { // 验证数据 this.validateQuoteData(data); // 调用价格计算逻辑 const pricing = await this.calculatePricing(data); // 返回结果 return { success: true, data: pricing, timestamp: new Date().toISOString() }; } private validateQuoteData(data: QuoteCalculationRequest): void { if (!data.productType) { throw new Error('Product type is required'); } } private async calculatePricing(data: QuoteCalculationRequest) { // 价格计算逻辑 } }
数据库操作规范
// ✅ 正确:API Routes 通过 Service 层访问数据库 export async function POST(request: Request) { const orderService = new OrderService(); const result = await orderService.createOrder(data); return NextResponse.json(result); }
📋 完整的数据库操作和分层架构规范请参考:数据层开发标准
📱 客户端API使用规范
🚫 强制禁令
1. 禁止直接使用fetch
❌ 绝对不要直接使用原生的 fetch
API进行HTTP请求:
// ❌ 禁止这样做 const response = await fetch('/api/order/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), });
2. 必须使用统一的API客户端
✅ 必须使用项目提供的统一API客户端:
方式1:使用结构化API客户端(推荐)
import { API } from '@/lib/api/client'; // 订单相关操作 const result = await API.order.submit(payload); const orderDetails = await API.order.getDetails(orderId); const updateResult = await API.order.update(orderId, updates); // 用户相关操作 const profile = await API.user.getProfile(); const addresses = await API.user.getAddresses();
方式2:使用便捷方法
import { request } from '@/lib/request'; const result = await request.get('/api/user/profile'); const response = await request.post('/api/order/submit', payload);
方式3:使用封装的服务层
import { submitOrder, getOrderDetails } from '@/lib/services/client/order.service'; const result = await submitOrder(payload); const details = await getOrderDetails(orderId);
客户端服务实现规范
服务文件要求
在 lib/services/client/
目录下的服务文件必须:
- ✅ 使用
API
客户端而不是直接的requestClient
- ✅ 包含必要的数据验证
- ✅ 提供清晰的类型定义
- ✅ 使用函数式编程而非类
// ✅ 正确的服务实现 export async function submitOrder(payload: CreateOrderPayload) { // 数据验证 if (!payload.cartItems?.length) { throw new Error('Cart is empty'); } // 使用API客户端 return await API.order.submit<SubmitOrderResponse>(payload); }
React中的API调用
// ✅ 正确:在React组件中使用API export function useQuoteCalculation() { const [loading, setLoading] = useState(false); const [error, setError] = useState<string | null>(null); const calculateQuote = useCallback(async (data: QuoteCalculationRequest) => { try { setLoading(true); setError(null); const result = await API.quote.calculate<QuoteCalculationResult>(data); return result; } catch (err) { setError(err instanceof Error ? err.message : 'Unknown error'); throw err; } finally { setLoading(false); } }, []); return { calculateQuote, loading, error }; }
🔒 类型安全要求
强制类型定义
- ✅ 必须为API调用指定明确的返回类型
- ✅ 必须定义请求和响应的接口
- ✅ 避免使用
any
类型
// ✅ 正确的类型使用 interface OrderResponse { success: boolean; orderId: string; message?: string; } const result = await API.order.submit<OrderResponse>(payload);
统一响应格式
interface ApiResponse<T> { success: boolean; data?: T; error?: string; code?: string; timestamp?: string; }
🚨 错误处理标准
统一错误处理
API客户端会自动处理HTTP错误,但业务层需要处理具体的业务错误:
// ✅ 正确的错误处理 try { const result = await API.order.submit(payload); return result; } catch (error) { if (error.status === 400) { throw new Error('Invalid order data'); } else if (error.status === 401) { throw new Error('Authentication required'); } throw error; }
服务端错误处理
// ✅ 正确:统一错误响应格式 export class APIError extends Error { constructor( message: string, public status: number = 500, public code?: string ) { super(message); this.name = 'APIError'; } } // API路由中的错误处理 export async function POST(request: NextRequest) { try { // 业务逻辑 } catch (error) { if (error instanceof APIError) { return NextResponse.json({ success: false, error: error.message, code: error.code }, { status: error.status }); } return NextResponse.json({ success: false, error: 'Internal server error' }, { status: 500 }); } }
📁 文件组织规范
客户端服务位置
- 所有客户端服务必须放在
lib/services/client/
目录 - 文件命名格式:
{resource}.service.ts
- 每个服务文件对应一个业务资源
API客户端扩展
如需添加新的API端点,请在 lib/api/client.ts
中添加:
// 添加新的API分组 public newResource: NewResourceAPI = { create: <T = any>(payload: any) => request.post<T>('/api/new-resource', payload), getDetails: <T = any>(id: string) => request.get<T>(`/api/new-resource/${id}`), };
🔍 HTTP状态码规范
标准状态码使用
200
- 请求成功201
- 资源创建成功400
- 客户端错误(验证失败等)401
- 未认证403
- 已认证但无权限404
- 资源不存在422
- 数据验证失败500
- 服务器内部错误
🔐 安全规范
认证和授权
// ✅ 正确:认证检查 export async function requireAuth(request: NextRequest) { const supabase = createClient(); const { data: { user } } = await supabase.auth.getUser(); if (!user) { throw new APIError('Authentication required', 401); } return user; } // ✅ 正确:管理员权限检查 export async function requireAdmin(request: NextRequest) { const user = await requireAuth(request); if (user.role !== 'admin') { throw new APIError('Admin access required', 403); } return user; }
数据验证
// ✅ 正确:输入验证 export function validateQuoteData(data: unknown): QuoteCalculationRequest { if (!data || typeof data !== 'object') { throw new APIError('Invalid data format', 400); } // 使用Zod或类似库进行验证 return data as QuoteCalculationRequest; }
安全最佳实践
- ✅ 所有API路由都进行认证检查
- ✅ 敏感操作需要额外权限验证
- ✅ 对所有用户输入进行验证和清理
- ✅ 使用HTTPS传输敏感数据
- ❌ 直接返回数据库错误给客户端
- ❌ 在客户端存储敏感信息
📋 代码审查清单
API类型定义检查
- 是否在正确的目录定义类型?(
types/api/
) - 是否使用了统一的命名约定?
- 是否避免了类型定义的重复?
- 页面组件是否直接导入了service类型?(❌ 禁止)
- 是否正确导入了API类型?
API路由检查
- 是否包含认证检查?
- 是否通过Service层处理业务逻辑?
- 是否使用统一的响应格式?
- 是否包含适当的错误处理?
客户端使用检查
- 是否使用了原生的
fetch
API? - 是否正确导入了API客户端?
- 是否提供了明确的类型定义?
- 是否包含了必要的数据验证?
- 错误处理是否恰当?
- 是否遵循了文件组织规范?
📚 相关文档
- 数据层开发标准:数据层开发标准
- API客户端使用指南:docs/guides/API_CLIENT_USAGE_GUIDE.md
- 新旧实现对比:docs/guides/API_CLIENT_COMPARISON.md
- 使用示例:examples/api-client-usage.tsx
遵循这些规范将确保项目的API开发和使用保持一致性、类型安全和易于维护。
- 追踪错误率
- 记录用户行为分析数据
🧭 Explore More
💬 Need Help?
Our PCB experts are here to help with your questions.
📞 +86-181-2860-9108
✉️ support@speedxpcb.com
🕒 24/7 Expert Support
🏆 Industry Leader
✓ 50,000+ Happy Customers
✓ ISO 9001:2015 Certified
✓ 99.8% Quality Rate
✓ 24hr Fast Turnaround