Skip to main content

backend-patterns

后端架构模式、API 设计、数据库优化,以及针对 Node.js、Express 和 Next.js API 路由的服务端最佳实践。

Quellinformationen

Repository
aaione/everything-claude-code-zh
Letzte Quellaktivität
31. Mai 2026 um 16:26
Erkannte Sprache von SKILL.md
Chinesisch
Sterne
30
Forks
14

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
backend-patterns
description
后端架构模式、API 设计、数据库优化,以及针对 Node.js、Express 和 Next.js API 路由的服务端最佳实践。
origin
ECC
# 后端开发模式 (Backend Development Patterns) 用于可扩展服务端应用程序的后端架构模式和最佳实践。 ## API 设计模式 ### RESTful API 结构 ```typescript // ✅ Resource-based URLs GET /api/markets # 列表资源 GET /api/markets/:id # 获取单个资源 POST /api/markets # 创建资源 PUT /api/markets/:id # 替换资源 PATCH /api/markets/:id # 更新资源 DELETE /api/markets/:id # 删除资源 // ✅ Query parameters for filtering, sorting, pagination GET /api/markets?status=active&sort=volume&limit=20&offset=0 ``` ### 仓库模式 (Repository Pattern) ```typescript // 抽象数据访问逻辑 interface MarketRepository { findAll(filters?: MarketFilters): Promise<Market[]> findById(id: string): Promise<Market | null> create(data: CreateMarketDto): Promise<Market> update(id: string, data: UpdateMarketDto): Promise<Market> delete(id: string): Promise<void> } class SupabaseMarketRepository implements MarketRepository { async findAll(filters?: MarketFilters): Promise<Market[]> { let query = supabase.from('markets').select('*') if (filters?.status) { query = query.eq('status', filters.status) } if (filters?.limit) { query = query.limit(filters.limit) } const { data, error } = await query if (error) throw new Error(error.message) return data } // Other methods... } ``` ### 服务层模式 (Service Layer Pattern) ```typescript // 业务逻辑与数据访问分离 class MarketService { constructor(private marketRepo: MarketRepository) {} async searchMarkets(query: string, limit: number = 10): Promise<Market[]> { // 业务逻辑 const embedding = await generateEmbedding(query) const results = await this.vectorSearch(embedding, limit) // 获取完整数据 const markets = await this.marketRepo.findByIds(results.map(r => r.id)) // 按相似度排序 return markets.sort((a, b) => { const scoreA = results.find(r => r.id === a.id)?.score || 0 const scoreB = results.find(r => r.id === b.id)?.score || 0 return scoreA - scoreB }) } private async vectorSearch(embedding: number[], limit: number) { // 向量搜索实现 } } ``` ### 中间件模式 (Middleware Pattern) ```typescript // 请求/响应处理管道 export function withAuth(handler: NextApiHandler): NextApiHandler { return async (req, res) => { const token = req.headers.authorization?.replace('Bearer ', '') if (!token) { return res.status(401).json({ error: 'Unauthorized' }) } try { const user = await verifyToken(token) req.user = user return handler(req, res) } catch (error) { return res.status(401).json({ error: 'Invalid token' }) } } } // 用法 export default withAuth(async (req, res) => { // 处理程序可以访问 req.user }) ``` ## 数据库模式 ### 查询优化 ```typescript // ✅ GOOD: 仅选择需要的列 const { data } = await supabase .from('markets') .select('id, name, status, volume') .eq('status', 'active') .order('volume', { ascending: false }) .limit(10) // ❌ BAD: 选择所有列 const { data } = await supabase .from('markets') .select('*') ``` ### N+1 查询预防 ```typescript // ❌ BAD: N+1 查询问题 const markets = await getMarkets() for (const market of markets) { market.creator = await getUser(market.creator_id) // N 个查询 } // ✅ GOOD: 批量获取 const markets = await getMarkets() const creatorIds = markets.map(m => m.creator_id) const creators = await getUsers(creatorIds) // 1 个查询 const creatorMap = new Map(creators.map(c => [c.id, c])) markets.forEach(market => { market.creator = creatorMap.get(market.creator_id) }) ``` ### 事务模式 (Transaction Pattern) ```typescript async function createMarketWithPosition( marketData: CreateMarketDto, positionData: CreatePositionDto ) { // 使用 Supabase 事务 const { data, error } = await supabase.rpc('create_market_with_position', { market_data: marketData, position_data: positionData }) if (error) throw new Error('Transaction failed') return data } // Supabase 中的 SQL 函数 CREATE OR REPLACE FUNCTION create_market_with_position( market_data jsonb, position_data jsonb ) RETURNS jsonb LANGUAGE plpgsql AS $$ BEGIN -- 自动开始事务 INSERT INTO markets VALUES (market_data); INSERT INTO positions VALUES (position_data); RETURN jsonb_build_object('success', true); EXCEPTION WHEN OTHERS THEN -- 自动回滚 RETURN jsonb_build_object('success', false, 'error', SQLERRM); END; $$; ``` ## 缓存策略 ### Redis 缓存层 ```typescript class CachedMarketRepository implements MarketRepository { constructor( private baseRepo: MarketRepository, private redis: RedisClient ) {} async findById(id: string): Promise<Market | null> { // 先检查缓存 const cached = await this.redis.get(`market:${id}`) if (cached) { return JSON.parse(cached) } // 缓存未命中 - 从数据库获取 const market = await this.baseRepo.findById(id) if (market) { // 缓存 5 分钟 await this.redis.setex(`market:${id}`, 300, JSON.stringify(market)) } return market } async invalidateCache(id: string): Promise<void> { await this.redis.del(`market:${id}`) } } ``` ### Cache-Aside 模式 ```typescript async function getMarketWithCache(id: string): Promise<Market> { const cacheKey = `market:${id}` // 尝试缓存 const cached = await redis.get(cacheKey) if (cached) return JSON.parse(cached) // 缓存未命中 - 从 DB 获取 const market = await db.markets.findUnique({ where: { id } }) if (!market) throw new Error('Market not found') // 更新缓存 await redis.setex(cacheKey, 300, JSON.stringify(market)) return market } ``` ## 错误处理模式 ### 集中式错误处理程序 ```typescript class ApiError extends Error { constructor( public statusCode: number, public message: string, public isOperational = true ) { super(message) Object.setPrototypeOf(this, ApiError.prototype) } } export function errorHandler(error: unknown, req: Request): Response { if (error instanceof ApiError) { return NextResponse.json({ success: false, error: error.message }, { status: error.statusCode }) } if (error instanceof z.ZodError) { return NextResponse.json({ success: false, error: 'Validation failed', details: error.errors }, { status: 400 }) } // 记录意外错误 console.error('Unexpected error:', error) return NextResponse.json({ success: false, error: 'Internal server error' }, { status: 500 }) } // Usage export async function GET(request: Request) { try { const data = await fetchData() return NextResponse.json({ success: true, data }) } catch (error) { return errorHandler(error, request) } } ``` ### 指数退避重试 (Retry with Exponential Backoff) ```typescript async function fetchWithRetry<T>( fn: () => Promise<T>, maxRetries = 3 ): Promise<T> { let lastError: Error for (let i = 0; i < maxRetries; i++) { try { return await fn() } catch (error) { lastError = error as Error if (i < maxRetries - 1) { // Exponential backoff: 1s, 2s, 4s const delay = Math.pow(2, i) * 1000 await new Promise(resolve => setTimeout(resolve, delay)) } } } throw lastError! } // Usage const data = await fetchWithRetry(() => fetchFromAPI()) ``` ## 认证 & 授权 (Authentication & Authorization) ### JWT Token 验证 ```typescript import jwt from 'jsonwebtoken' interface JWTPayload { userId: string email: string role: 'admin' | 'user' } export function verifyToken(token: string): JWTPayload { try { const payload = jwt.verify(token, process.env.JWT_SECRET!) as JWTPayload return payload } catch (error) { throw new ApiError(401, 'Invalid token') } } export async function requireAuth(request: Request) { const token = request.headers.get('authorization')?.replace('Bearer ', '') if (!token) { throw new ApiError(401, 'Missing authorization token') } return verifyToken(token) } // 在 API 路由中使用 export async function GET(request: Request) { const user = await requireAuth(request) const data = await getDataForUser(user.userId) return NextResponse.json({ success: true, data }) } ``` ### 基于角色的访问控制 (RBAC) ```typescript type Permission = 'read' | 'write' | 'delete' | 'admin' interface User { id: string role: 'admin' | 'moderator' | 'user' } const rolePermissions: Record<User['role'], Permission[]> = { admin: ['read', 'write', 'delete', 'admin'], moderator: ['read', 'write', 'delete'], user: ['read', 'write'] } export function hasPermission(user: User, permission: Permission): boolean { return rolePermissions[user.role].includes(permission) } export function requirePermission(permission: Permission) { return (handler: (request: Request, user: User) => Promise<Response>) => { return async (request: Request) => { const user = await requireAuth(request) if (!hasPermission(user, permission)) { throw new ApiError(403, 'Insufficient permissions') } return handler(request, user) } } } // 用法 - HOF 包装处理程序 export const DELETE = requirePermission('delete')( async (request: Request, user: User) => { // 处理程序接收经过身份验证且具有已验证权限的用户 return new Response('Deleted', { status: 200 }) } ) ``` ## 速率限制 (Rate Limiting) ### 简单的内存速率限制器 ```typescript class RateLimiter { private requests = new Map<string, number[]>() async checkLimit( identifier: string, maxRequests: number, windowMs: number ): Promise<boolean> { const now = Date.now() const requests = this.requests.get(identifier) || [] // 移除窗口外的旧请求 const recentRequests = requests.filter(time => now - time < windowMs) if (recentRequests.length >= maxRequests) { return false // Rate limit exceeded } // 添加当前请求 recentRequests.push(now) this.requests.set(identifier, recentRequests) return true } } const limiter = new RateLimiter() export async function GET(request: Request) { const ip = request.headers.get('x-forwarded-for') || 'unknown' const allowed = await limiter.checkLimit(ip, 100, 60000) // 100 req/min if (!allowed) { return NextResponse.json({ error: 'Rate limit exceeded' }, { status: 429 }) } // 继续请求 } ``` ## 后台任务 & 队列 ### 简单队列模式 ```typescript class JobQueue<T> { private queue: T[] = [] private processing = false async add(job: T): Promise<void> { this.queue.push(job) if (!this.processing) { this.process() } } private async process(): Promise<void> { this.processing = true while (this.queue.length > 0) { const job = this.queue.shift()! try { await this.execute(job) } catch (error) { console.error('Job failed:', error) } } this.processing = false } private async execute(job: T): Promise<void> { // Job execution logic } } // 用于索引市场的用法 interface IndexJob { marketId: string } const indexQueue = new JobQueue<IndexJob>()
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen