Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes.
.claude/skills/backend-patterns/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 136% | 0% |
| case-08 | ✓→✓ | = Same ✓ | 130% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 150% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 214% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 168% | 0% |
Backend architecture patterns and best practices for scalable server-side applications.
typescript// PASS: 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 // PASS: Query parameters for filtering, sorting, pagination GET /api/markets?status=active&sort=volume&limit=20&offset=0
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... }
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 } }
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 })
typescript// PASS: 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) // FAIL: BAD: Select everything const { data } = await supabase .from('markets') .select('*')
typescript// FAIL: BAD: N+1 query problem const markets = await getMarkets() for (const market of markets) { market.creator = await getUser(market.creator_id) // N queries } // PASS: 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) })
typescriptasync 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; $$;
typescriptclass 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}`) } }
typescriptasync 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 }
typescriptclass 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.issues }, { 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) } }
typescriptasync 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())
typescriptimport 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) } // Usage in API route export async function GET(request: Request) { const user = await requireAuth(request) const data = await getDataForUser(user.userId) return NextResponse.json({ success: true, data }) }
typescripttype 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) } } } // Usage - HOF wraps the handler export const DELETE = requirePermission('delete')( async (request: Request, user: User) => { // Handler receives authenticated user with verified permission return new Response('Deleted', { status: 200 }) } )
Rate limiting must use a shared store such as Redis, a gateway, or the platform's native limiter. Do not use per-process in-memory counters for production APIs: they reset on deploy, split across replicas, and fail open in serverless or multi-instance environments.
Keep the backend layer responsible for choosing the integration point and error shape; use api-design for the HTTP contract and security-review for abuse case review.
typescriptclass 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 } } // Usage for indexing markets interface IndexJob { marketId: string } const indexQueue = new JobQueue<IndexJob>() export async function POST(request: Request) { const { marketId } = await request.json() // Add to queue instead of blocking await indexQueue.add({ marketId }) return NextResponse.json({ success: true, message: 'Job queued' }) }
typescriptinterface LogContext { userId?: string requestId?: string method?: string path?: string [key: string]: unknown } class Logger { log(level: 'info' | 'warn' | 'error', message: string, context?: LogContext) { const entry = { timestamp: new Date().toISOString(), level, message, ...context } console.log(JSON.stringify(entry)) } info(message: string, context?: LogContext) { this.log('info', message, context) } warn(message: string, context?: LogContext) { this.log('warn', message, context) } error(message: string, error: Error, context?: LogContext) { this.log('error', message, { ...context, error: error.message, stack: error.stack }) } } const logger = new Logger() // Usage export async function GET(request: Request) { const requestId = crypto.randomUUID() logger.info('Fetching markets', { requestId, method: 'GET', path: '/api/markets' }) try { const markets = await fetchMarkets() return NextResponse.json({ success: true, data: markets }) } catch (error) { logger.error('Failed to fetch markets', error as Error, { requestId }) return NextResponse.json({ error: 'Internal error' }, { status: 500 }) } }
Remember: Backend patterns enable scalable, maintainable server-side applications. Choose patterns that fit your complexity level.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-08 | pass→pass | 12,824 | 9,071 | -29% | 1 | 1 | 0% | 2,363 | 5,434 | +130% | 0 | 0 | — |
case-01 | pass→pass | 9,238 | 6,411 | -31% | 1 | 1 | 0% | 1,940 | 4,845 | +150% | 0 | 0 | — |
case-02 | pass→pass | 7,687 | 4,729 | -38% | 1 | 1 | 0% | 1,390 | 4,367 | +214% | 0 | 0 | — |
case-03 | pass→pass | 9,490 | 6,977 | -26% | 1 | 1 | 0% | 1,873 | 5,026 | +168% | 0 | 0 | — |
case-04 | pass→pass | 12,436 | 7,924 | -36% | 1 | 1 | 0% | 2,376 | 5,094 | +114% | 0 | 0 | — |
case-05 | fail→pass | 10,340 | 6,425 | -38% | 1 | 1 | 0% | 2,091 | 4,935 | +136% | 0 | 0 | — |
case-06 | pass→pass | 5,352 | 4,330 | -19% | 1 | 1 | 0% | 1,088 | 4,446 | +309% | 0 | 0 | — |
case-07 | pass→pass | 14,146 | 10,455 | -26% | 1 | 1 | 0% | 2,505 | 5,607 | +124% | 0 | 0 | — |
case-09 | pass→pass | 15,360 | 11,984 | -22% | 1 | 1 | 0% | 3,175 | 5,799 | +83% | 0 | 0 | — |
case-10 | pass→pass | 10,198 | 5,689 | -44% | 1 | 1 | 0% | 2,136 | 4,702 | +120% | 0 | 0 | — |
case-11 | pass→pass | 11,821 | 9,475 | -20% | 1 | 1 | 0% | 2,361 | 5,422 | +130% | 0 | 0 | — |
case-12 | pass→pass | 9,171 | 7,462 | -19% | 1 | 1 | 0% | 1,745 | 4,988 | +186% | 0 | 0 | — |
case-13 | pass→pass | 8,246 | 5,507 | -33% | 1 | 1 | 0% | 1,558 | 4,635 | +197% | 0 | 0 | — |
case-14 | pass→pass | 12,496 | 9,117 | -27% | 1 | 1 | 0% | 2,458 | 5,591 | +127% | 0 | 0 | — |
case-15 | pass→pass | 14,405 | 10,222 | -29% | 1 | 1 | 0% | 3,155 | 5,650 | +79% | 0 | 0 | — |
case-16 | pass→pass | 6,371 | 5,813 | -9% | 1 | 1 | 0% | 1,037 | 4,563 | +340% | 0 | 0 | — |
case-17 | pass→pass | 9,956 | 6,738 | -32% | 1 | 1 | 0% | 1,806 | 4,856 | +169% | 0 | 0 | — |
case-18 | pass→pass | 7,713 | 4,434 | -43% | 1 | 1 | 0% | 1,500 | 4,452 | +197% | 0 | 0 | — |
case-19 | pass→pass | 8,121 | 4,004 | -51% | 1 | 1 | 0% | 1,389 | 4,273 | +208% | 0 | 0 | — |
case-20 | pass→pass | 6,323 | 3,053 | -52% | 1 | 1 | 0% | 1,145 | 4,149 | +262% | 0 | 0 | — |
case-21 | pass→pass | 7,020 | 5,856 | -17% | 1 | 1 | 0% | 1,490 | 4,904 | +229% | 0 | 0 | — |
case-22 | pass→pass | 19,614 | 14,636 | -25% | 1 | 1 | 0% | 2,678 | 6,058 | +126% | 0 | 0 | — |
case-23 | pass→pass | 12,519 | 8,403 | -33% | 1 | 1 | 0% | 2,386 | 5,232 | +119% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +4 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/27/2026 | +9% |
Other measured skills in the registry, with their headline benchmark lift.