Skip to main content

backend-patterns

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

معلومات المصدر

المستودع
joneqian/claude-skills-suite
آخر نشاط في المصدر
٢٧ يناير ٢٠٢٦ في ٠٨:٢٤
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٣٢
التفرعات
٤

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
backend-patterns
description
Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, NestJS, FastAPI, and Next.js API routes.
# Backend Development Patterns Backend architecture patterns and best practices for scalable server-side applications. ## Framework-Specific Guidelines When working with specific frameworks, combine this skill with framework-specific skills: | Framework | Additional Skill | When to Use | | --------------- | ----------------------------- | ---------------------------------------------------------------- | | **NestJS** | `nestjs-best-practices` skill | Modules, Controllers, Providers, Guards, Interceptors, Pipes, DI | | **FastAPI** | `fastapi-templates` skill | Routes, Decorators, DI, GraphQL, Microservices | | **Next.js API** | This skill only | Serverless API routes | ### NestJS Integration When using **NestJS**, the patterns in this skill should be adapted to NestJS conventions: | Generic Pattern | NestJS Implementation | | ------------------ | ------------------------------------------------------------ | | Repository Pattern | Use `@Injectable()` repositories with DI | | Service Layer | Use `@Injectable()` services | | Middleware | Use NestJS `@Injectable()` middleware or Guards/Interceptors | | Error Handling | Use Exception Filters (`@Catch()`) | | Validation | Use Pipes with `class-validator` | | Auth Middleware | Use Guards (`@UseGuards()`) | | Rate Limiting | Use `@nestjs/throttler` module | **Example - NestJS Repository Pattern:** ```typescript // NestJS style with dependency injection @Injectable() export class MarketRepository { constructor( @InjectRepository(Market) private marketRepo: Repository<Market>, ) {} async findAll(filters?: MarketFilters): Promise<Market[]> { const query = this.marketRepo.createQueryBuilder('market'); if (filters?.status) { query.where('market.status = :status', { status: filters.status }); } return query.getMany(); } } // Inject into service @Injectable() export class MarketService { constructor(private marketRepo: MarketRepository) {} } ``` **Example - NestJS Error Handling:** ```typescript // Exception filter instead of middleware error handler @Catch() export class AllExceptionsFilter implements ExceptionFilter { catch(exception: unknown, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse<Response>(); if (exception instanceof HttpException) { return response.status(exception.getStatus()).json({ success: false, error: exception.message, }); } return response.status(500).json({ success: false, error: 'Internal server error', }); } } ``` > **Tip**: For NestJS-specific decorators, modules, and advanced features (GraphQL, Microservices, WebSockets), refer to the **nestjs skill** for detailed documentation. ## API Design Patterns ### RESTful API Structure ```typescript // ✅ Resource-based URLs GET /api/markets # List resources GET /api/markets/:id # Get single resource POST /api/markets # Create resource PUT /api/markets/:id # Replace resource PATCH /api/markets/:id # Update resource DELETE /api/markets/:id # Delete resource // ✅ Query parameters for filtering, sorting, pagination GET /api/markets?status=active&sort=volume&limit=20&offset=0 ``` ### Repository Pattern ```typescript // Abstract data access logic 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 // Business logic separated from data access class MarketService { constructor(private marketRepo: MarketRepository) {} async searchMarkets(query: string, limit: number = 10): Promise<Market[]> { // Business logic const embedding = await generateEmbedding(query); const results = await this.vectorSearch(embedding, limit); // Fetch full data const markets = await this.marketRepo.findByIds(results.map((r) => r.id)); // Sort by similarity 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) { // Vector search implementation } } ``` ### Middleware Pattern ```typescript // Request/response processing pipeline 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' }); } }; } // Usage export default withAuth(async (req, res) => { // Handler has access to req.user }); ``` ## Database Patterns ### Query Optimization ```typescript // ✅ GOOD: Select only needed columns const { data } = await supabase .from('markets') .select('id, name, status, volume') .eq('status', 'active') .order('volume', { ascending: false }) .limit(10); // ❌ BAD: Select everything const { data } = await supabase.from('markets').select('*'); ``` ### N+1 Query Prevention ```typescript // ❌ BAD: N+1 query problem const markets = await getMarkets(); for (const market of markets) { market.creator = await getUser(market.creator_id); // N queries } // ✅ GOOD: Batch fetch const markets = await getMarkets(); const creatorIds = markets.map((m) => m.creator_id); const creators = await getUsers(creatorIds); // 1 query 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 ) { // Use Supabase transaction 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 } // SQL function in Supabase CREATE OR REPLACE FUNCTION create_market_with_position( market_data jsonb, position_data jsonb ) RETURNS jsonb LANGUAGE plpgsql AS $$ BEGIN -- Start transaction automatically INSERT INTO markets VALUES (market_data); INSERT INTO positions VALUES (position_data); RETURN jsonb_build_object('success', true); EXCEPTION WHEN OTHERS THEN -- Rollback happens automatically RETURN jsonb_build_object('success', false, 'error', SQLERRM); END; $$; ``` ## Caching Strategies ### Redis Caching Layer ```typescript class CachedMarketRepository implements MarketRepository { constructor( private baseRepo: MarketRepository, private redis: RedisClient, ) {} async findById(id: string): Promise<Market | null> { // Check cache first const cached = await this.redis.get(`market:${id}`); if (cached) { return JSON.parse(cached); } // Cache miss - fetch from database const market = await this.baseRepo.findById(id); if (market) { // Cache for 5 minutes 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 Pattern ```typescript async function getMarketWithCache(id: string): Promise<Market> { const cacheKey = `market:${id}`; // Try cache const cached = await redis.get(cacheKey); if (cached) return JSON.parse(cached); // Cache miss - fetch from DB const market = await db.markets.findUnique({ where: { id } }); if (!market) throw new Error('Market not found'); // Update cache await redis.setex(cacheKey, 300, JSON.stringify(market)); return market; } ``` ## Error Handling Patterns ### Centralized Error Handler ```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 }, ); } // Log unexpected errors 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 Validation ```typescript import jwt from 'jsonwebtoken'; interface JWTPayload { userId: string; email: string;
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub