Skills Plugins MCP Prompt Model 博客 我的中心

backend-patterns

Node.js, Express, Next.js API 라우트를 위한 백엔드 아키텍처 패턴, API 설계, 데이터베이스 최적화 및 서버 사이드 모범 사례.

DeepseekModel 官方收录技能 质量 优秀 · 90 v1.0.0

获取

https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-docs-ko-kr-skills-backend-patterns-skill-md&format=skill
下载 .skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name backend-patterns description Node.js, Express, Next.js API 라우트를 위한 백엔드 아키텍처 패턴, API 설계, 데이터베이스 최적화 및 서버 사이드 모범 사례. origin ECC 백엔드 개발 패턴 확장 가능한 서버 사이드 애플리케이션을 위한 백엔드 아키텍처 패턴과 모범 사례. 활성화 시점 REST 또는 GraphQL API 엔드포인트를 설계할 때 Repository, Service 또는 Controller 레이어를 구현할 때 데이터베이스 쿼리를 최적화할 때 (N+1, 인덱싱, 커넥션 풀링) 캐싱을 추가할 때 (Redis, 인메모리, HTTP 캐시 헤더) 백그라운드 작업이나 비동기 처리를 설정할 때 API를 위한 에러 처리 및 유효성 검사를 구조화할 때 미들웨어를 구축할 때 (인증, 로깅, 요청 제한) API 설계 패턴 RESTful API 구조 // 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 Repository 패턴 // Abstract data access logic interface MarketRepository { findAll ( filters ?: MarketFilters ): Promise < Market []> findById ( id : string ): Promise < Market | null > findByIds ( ids : string []): Promise < Market []> 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 레이어 패턴 // 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 } } 미들웨어 패턴 // 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 }) 데이터베이스 패턴 쿼리 최적화 // 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 ( '*' ) N+1 쿼리 방지 // 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 ) }) 트랜잭션 패턴 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 ; $$; 캐싱 전략 Redis 캐싱 레이어 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 패턴 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 } 에러 처리 패턴 중앙화된 에러 핸들러 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) } } 지수 백오프를 이용한 재시도 async function fetchWithRetry<T>( fn : () => Promise <T>, maxRetries = 3 ): Promise <T> { let lastError : Error = new Error ( 'Retry attempts exhausted' ) 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 ()) 인증 및 인가 JWT 토큰 검증 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) } // 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 }) } 역할 기반 접근 제어 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) } } } // 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 }) } ) 요청 제한 간단한 인메모리 요청 제한기 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) || [] // Remove old requests outside window const recentRequests = requests. filter ( time => now - time < windowMs) if (recentRequests. length >= maxRequests) { return false // Rate limit exceeded } // Add current request 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 }) } // Continue with request } 백그라운드 작업 및 큐 간단한 큐 패턴 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) } }
Agent 识别该技能的关键词,点击任意一个即可复制。

该技能未提供触发词。

下载的 .skill 包内含以下字段。
字段 说明
format格式标识(skill/v1)
skill_id技能唯一 ID
name技能名称
version版本号
description技能描述
category所属分类(数组)
trigger_words触发词列表
tags标签列表
source来源标识
source_url来源链接(本页地址)
exported_at导出时间(每次下载生成)
system_prompt系统提示词正文
model_config模型参数:provider / model / temperature / max_tokens / top_p
examples示例
install_guide各平台导入说明(Coze / Dify / Claude / 自定义框架)
同一份技能可按不同平台格式导出。
.skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用 下载
.skillpro 增强格式,额外含脚本 / 工具 / 依赖 / 钩子占位 下载
.json 纯 JSON 导出,只含 system_prompt 与模型参数 下载
Coze 带 frontmatter 的 Markdown,Coze 平台导入用 下载
Dify Dify DSL,创建应用后直接导入 下载

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。