Skip to main content 홈 크리에이터 chloevpin candy-skills api-route-structure
api-route-structure HACER CUMPLIR un diseño de API REST consistente y predecible. Las URLs identifican recursos (sustantivos). Los métodos HTTP definen acciones (verbos). Las respuestas siguen un envoltorio consistente. Prevenir endpoints estilo RPC, formatos de respuesta inconsistentes y respuestas de datos sin límites. Activadores: "build an API", "create (a|an|a new) endpoint", "set up (the) backend routes".
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/ChloeVPin/candy-skills --skill api-route-structure명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... name API Route Structure description HACER CUMPLIR un diseño de API REST consistente y predecible. Las URLs identifican recursos (sustantivos). Los métodos HTTP definen acciones (verbos). Las respuestas siguen un envoltorio consistente. Prevenir endpoints estilo RPC, formatos de respuesta inconsistentes y respuestas de datos sin límites. Activadores: "build an API", "create (a|an|a new) endpoint", "set up (the) backend routes".
category backend version 3.0.0 last_updated 2026-06-28T00:00:00.000Z stacks ["Express","FastAPI","Next.js 16 (Route Handlers)","Nuxt (Nitro)","Django"] related_skills ["backend-validation-layers","production-api-error-handling","database-schema-design"] lang es direction ltr source_version 3.0.0 translated_at 2026-06-29T00:00:00.000Z
Estructura de Rutas API
IDENTIFICAR: Cuándo activarse
Activar cuando:
Se define cómo se comunica el frontend con el backend
Se expone una API pública o interna
Se añaden nuevos endpoints a una API existente
El usuario dice "build an API" o "create a new endpoint"
REGLAS DE DISEÑO DE URL
Regla 1: Sustantivos, Nunca Verbos
✅ GET /api/users , listar usuarios
✅ POST /api/users , crear usuario
❌ POST /api/getUsers , verbo en URL
❌ GET /api/createUser , verbo en URL
Regla 2: Sustantivos en Plural para Colecciones
✅ /api/users
✅ /api/orders
❌ /api/user
❌ /api/order
Regla 3: Parámetros de Ruta para Recursos Específicos
✅ GET /api/users/abc123
✅ PATCH /api/users/abc123
✅ DELETE /api/users/abc123
Regla 4: Máximo 1 Nivel de Anidamiento
✅ GET /api/users/abc123/orders
❌ GET /api/users/abc123/orders/xyz789/items/def456
Para anidamiento más profundo, consultar el sub-recurso directamente: GET /api/items/def456
Regla 5: Parámetros de Consulta para Filtrado, Ordenamiento, Paginación
GET /api/users?status=active&sort=created_at&page=2&limit=20
Semántica de Métodos HTTP
Método Acción Ejemplo ¿Idempotente? ¿Cuerpo de solicitud? GETListar / Leer GET /api/usersSí No POSTCrear POST /api/usersNo Sí PATCHActualizar parcialmente PATCH /api/users/:idNo Sí PUTReemplazar completamente PUT /api/users/:idSí Sí DELETEEliminar DELETE /api/users/:idSí No
Envoltorio de Respuesta: SIEMPRE Consistente
Éxito (Colección)
{
"data" : [ { "id" : "1" , "name" : "Alice" } ] ,
"meta" : { "total" : 42 , "page" : 1 , "limit" : 20 }
}
Éxito (Recurso Único) {
"data" : { "id" : "1" , "name" : "Alice" }
}
Error: Formato RFC 9457 Problem Details {
"error" : { "message" : "User not found" , "status" : 404 }
}
Selección de Códigos de Estado Código Usar para Nunca usar para 200 OKGET, PATCH, PUT exitosos Errores (no devolver 200 con cuerpo de error) 201 CreatedPOST exitoso Cualquier otra cosa 204 No ContentDELETE exitoso Respuestas con cuerpo 400 Bad RequestFallo de validación, entrada malformada Errores del servidor (usar 500) 401 UnauthorizedCredenciales faltantes/inválidas Errores de permiso (usar 403) 403 ForbiddenCredenciales válidas, permisos insuficientes Credenciales faltantes (usar 401) 404 Not FoundEl recurso no existe Errores de validación (usar 400) 409 ConflictRecurso duplicado, conflicto de estado Errores de validación (usar 400) 422 UnprocessableFallo de validación semántica Errores de análisis sintáctico (usar 400) 429 Too Many RequestsLímite de tasa excedido Errores de autenticación 500 Internal Server ErrorFallo inesperado del servidor Errores esperados (usar 4xx)
Paginación: SIEMPRE Requerida Cada endpoint de colección DEBE soportar paginación.
Basada en Cursor (PREFERIDA: estable bajo alto volumen de inserciones) GET /api/users?cursor=abc123&limit=20
Respuesta: { "data": [...], "meta": { "next_cursor": "def456", "has_more": true } }
Basada en Desplazamiento (aceptable para conjuntos de datos pequeños y estables) GET /api/users?page=1&limit=20
Respuesta: { "data": [...], "meta": { "total": 100, "page": 1, "limit": 20 } }
Límite por defecto: 20
Límite máximo: 100
SIEMPRE devolver conteo total (desplazamiento) o bandera has_more (cursor)
Implementación CRUD: SIEMPRE Implementar TODAS las Operaciones Para cada recurso, implementar LAS SEIS operaciones. Nunca detenerse en GET y POST:
router.get ('/' , listUsers);
router.post ('/' , createUser);
router.get ('/:id' , getUser);
router.put ('/:id' , replaceUser);
router.patch ('/:id' , updateUser);
router.delete ('/:id' , deleteUser);
Patrones Específicos por Stack
Next.js 16 Route Handlers (App Router) Enrutamiento basado en archivos:
app/api/users/route.ts → GET /api/users, POST /api/users
app/api/users/[id]/route.ts → GET /api/users/:id, PATCH, DELETE
import { NextRequest , NextResponse } from 'next/server' ;
export async function GET (request : NextRequest ) {
const { searchParams } = new URL (request.url );
const page = parseInt (searchParams.get ('page' ) || '1' );
const limit = parseInt (searchParams.get ('limit' ) || '20' );
const users = await db.user .findMany ({ skip : (page - 1 ) * limit, take : limit });
const total = await db.user .count ();
return NextResponse .json ({ data : users, meta : { total, page, limit } });
}
export async function POST (request : NextRequest ) {
const body = await request.json ();
const validated = CreateUserSchema .parse (body);
const user = await db.user .create ({ data : validated });
return NextResponse .json ({ data : user }, { status : 201 });
}
Express import { Router } from 'express' ;
const router = Router ();
router.get ('/' , listUsers);
router.post ('/' , createUser);
router.get ('/:id' , getUser);
router.put ('/:id' , replaceUser);
router.patch ('/:id' , updateUser);
router.delete ('/:id' , deleteUser);
FastAPI from fastapi import APIRouter, Query
router = APIRouter(prefix="/users" , tags=["users" ])
@router.get("/" )
async def list_users (page: int = Query(1 , ge=1 ), limit: int = Query(20 , ge=1 , le=100 ) ):
pass
@router.post("/" , status_code=201 )
async def create_user (body: UserCreate ):
pass
@router.get("/{user_id}" )
async def get_user (user_id: str ):
pass
VALIDAR: Puertas de Calidad
ANTIPATRONES: SIEMPRE Evitar Antipatrón Por qué está mal Solución POST /api/getUsersEstilo RPC. Rompe la semántica HTTP. Confunde el caché. GET /api/users200 OK con cuerpo de errorEngañoso. El cliente verifica el estado, no el cuerpo. Devolver el código 4xx correcto /api/users/:uid/posts/:pid/comments/:cidAnidamiento ilegible y frágil GET /api/comments/:cid10,000 filas, sin paginación Se agota el tiempo, bloquea clientes, agota la memoria Siempre paginar. Por defecto 20, máximo 100. Solo GET + POST implementados Faltan PUT/PATCH/DELETE Implementar LAS SEIS operaciones CRUD
SALIDA: Qué Produce Esta Habilidad {
"resources" : [ { "name" : "string" , "endpoints" : [ "GET /" , "POST /" , "GET /:id" , "PUT /:id" , "PATCH /:id" , "DELETE /:id" ] } ] ,
"pagination" : "cursor | offset" ,
"envelope" : { "success" : "{ data, meta }" , "error" : "{ error: { message, status } }" } ,
"framework" : "express | nextjs | fastapi | django"
}