返回顶部
b

backend-patterns后端架构模式

Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes.

作者: admin | 来源: ClawHub
源自
ClawHub
版本
V 0.1.2
安全检测
已通过
5,451
下载量
免费
免费
4
收藏
概述
安装方式
版本历史

backend-patterns

后端开发模式

适用于可扩展服务器端应用的后端架构模式和最佳实践。

API设计模式

RESTful API结构

typescript
// ✅ 基于资源的URL
GET /api/markets # 列出资源
GET /api/markets/:id # 获取单个资源
POST /api/markets # 创建资源
PUT /api/markets/:id # 替换资源
PATCH /api/markets/:id # 更新资源
DELETE /api/markets/:id # 删除资源

// ✅ 用于过滤、排序、分页的查询参数
GET /api/markets?status=active&sort=volume&limit=20&offset=0

仓储模式

typescript
// 抽象数据访问逻辑
interface MarketRepository {
findAll(filters?: MarketFilters): Promise
findById(id: string): Promise
create(data: CreateMarketDto): Promise
update(id: string, data: UpdateMarketDto): Promise
delete(id: string): Promise
}

class SupabaseMarketRepository implements MarketRepository {
async findAll(filters?: MarketFilters): Promise {
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
}

// 其他方法...
}

服务层模式

typescript
// 业务逻辑与数据访问分离
class MarketService {
constructor(private marketRepo: MarketRepository) {}

async searchMarkets(query: string, limit: number = 10): Promise {
// 业务逻辑
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) {
// 向量搜索实现
}
}

中间件模式

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: 未授权 })
}

try {
const user = await verifyToken(token)
req.user = user
return handler(req, res)
} catch (error) {
return res.status(401).json({ error: 无效的令牌 })
}
}
}

// 使用方式
export default withAuth(async (req, res) => {
// 处理程序可以访问 req.user
})

数据库模式

查询优化

typescript
// ✅ 良好实践:仅选择需要的列
const { data } = await supabase
.from(markets)
.select(id, name, status, volume)
.eq(status, active)
.order(volume, { ascending: false })
.limit(10)

// ❌ 不良实践:选择所有内容
const { data } = await supabase
.from(markets)
.select(*)

N+1查询预防

typescript
// ❌ 不良实践:N+1查询问题
const markets = await getMarkets()
for (const market of markets) {
market.creator = await getUser(market.creator_id) // N次查询
}

// ✅ 良好实践:批量获取
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)
})

事务模式

typescript
async function createMarketWithPosition(
marketData: CreateMarketDto,
positionData: CreatePositionDto
) {
// 使用Supabase事务
const { data, error } = await supabase.rpc(createmarketwith_position, {
market_data: marketData,
position_data: positionData
})

if (error) throw new Error(事务失败)
return data
}

// Supabase中的SQL函数
CREATE OR REPLACE FUNCTION createmarketwith_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 jsonbbuildobject(success, true);
EXCEPTION
WHEN OTHERS THEN
-- 自动回滚
RETURN jsonbbuildobject(success, false, error, SQLERRM);
END;
$$;

缓存策略

Redis缓存层

typescript
class CachedMarketRepository implements MarketRepository {
constructor(
private baseRepo: MarketRepository,
private redis: RedisClient
) {}

async findById(id: string): Promise {
// 先检查缓存
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 {
await this.redis.del(market:${id})
}
}

缓存旁路模式

typescript
async function getMarketWithCache(id: string): Promise {
const cacheKey = market:${id}

// 尝试缓存
const cached = await redis.get(cacheKey)
if (cached) return JSON.parse(cached)

// 缓存未命中 - 从数据库获取
const market = await db.markets.findUnique({ where: { id } })

if (!market) throw new Error(市场未找到)

// 更新缓存
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: 验证失败,
details: error.errors
}, { status: 400 })
}

// 记录意外错误
console.error(意外错误:, error)

return NextResponse.json({
success: false,
error: 内部服务器错误
}, { status: 500 })
}

// 使用方式
export async function GET(request: Request) {
try {
const data = await fetchData()
return NextResponse.json({ success: true, data })
} catch (error) {
return errorHandler(error, request)
}
}

指数退避重试

typescript
async function fetchWithRetry(
fn: () => Promise,
maxRetries = 3
): Promise {
let lastError: Error

for (let i = 0; i < maxRetries; i++) {
try {
return await fn()
} catch (error) {
lastError = error as Error

if (i < maxRetries - 1) {
// 指数退避:1秒、2秒、4秒
const delay = Math.pow(2, i) * 1000
await new Promise(resolve => setTimeout(resolve, delay))
}
}
}

throw lastError!
}

// 使用方式
const data = await fetchWithRetry(() => fetchFromAPI

标签

skill ai

通过对话安装

该技能支持在以下平台通过对话安装:

OpenClaw WorkBuddy QClaw Kimi Claude

方式一:安装 SkillHub 和技能

帮我安装 SkillHub 和 backend-patterns-1776373867 技能

方式二:设置 SkillHub 为优先技能安装源

设置 SkillHub 为我的优先技能安装源,然后帮我安装 backend-patterns-1776373867 技能

通过命令行安装

skillhub install backend-patterns-1776373867

下载

⬇ 下载 backend-patterns v0.1.2(免费)

文件大小: 4.93 KB | 发布时间: 2026-4-17 15:01

v0.1.2 最新 2026-4-17 15:01
Version 0.1.2 of backend-patterns

- No file changes detected in this release.
- No updates to features, documentation, or code.

Archiver·手机版·闲社网·闲社论坛·羊毛社区· 多链控股集团有限公司 · 苏ICP备2025199260号-1

Powered by Discuz! X5.0   © 2024-2025 闲社网·线报更新论坛·羊毛分享社区·http://xianshe.com

p2p_official_large
返回顶部