원클릭으로
api-design
REST API design patterns. Use when designing endpoints, defining schemas, or establishing API conventions.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
REST API design patterns. Use when designing endpoints, defining schemas, or establishing API conventions.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | api-design |
| description | REST API design patterns. Use when designing endpoints, defining schemas, or establishing API conventions. |
1. Resource-Oriented Design
# Good: Nouns for resources
GET /users → List users
POST /users → Create user
GET /users/{id} → Get user
PUT /users/{id} → Replace user
PATCH /users/{id} → Update user fields
DELETE /users/{id} → Delete user
GET /users/{id}/posts → User's posts (nested resource)
# Bad: Verbs in paths
POST /createUser
GET /getUsers
POST /deleteUser/{id}
2. HTTP Status Codes (Use Them Correctly)
200 OK — Success with body
201 Created — Resource created (include Location header)
204 No Content — Success, no body (DELETE, some PATCHes)
400 Bad Request — Client sent invalid data
401 Unauthorized — Not authenticated
403 Forbidden — Authenticated but not authorized
404 Not Found — Resource doesn't exist
409 Conflict — State conflict (duplicate, version mismatch)
422 Unprocessable — Validation failed
429 Too Many Req. — Rate limited
500 Internal Error — Server bug (should never leak details)
3. Consistent Error Response
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{"field": "email", "message": "Invalid email format"},
{"field": "age", "message": "Must be 18 or older"}
]
}
}
Always: same error shape across all endpoints. Never: different error formats in different routes.
4. Versioning
/api/v1/users — URL versioning (most common, visible)
/api/v2/users — New version for breaking changes
5. Pagination
{
"data": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"has_next": true
}
}
6. Input Validation at Boundary
# FastAPI with Pydantic
class CreateUserRequest(BaseModel):
email: EmailStr
name: str = Field(min_length=1, max_length=100)
age: int = Field(ge=18)
@router.post("/users", status_code=201)
async def create_user(data: CreateUserRequest) -> UserResponse:
...
<review_checklist> When reviewing an API design:
<language_examples>
from fastapi import APIRouter, HTTPException, status
from pydantic import BaseModel, EmailStr, Field
router = APIRouter(prefix="/users", tags=["users"])
class CreateUserRequest(BaseModel):
name: str = Field(min_length=1, max_length=100)
email: EmailStr
class UserResponse(BaseModel):
id: int
name: str
email: str
@router.post("", status_code=status.HTTP_201_CREATED, response_model=UserResponse)
async def create_user(data: CreateUserRequest, db: Session = Depends(get_db)):
if await db.get_by_email(data.email):
raise HTTPException(status.HTTP_409_CONFLICT, "Email already registered")
user = await db.create_user(data)
return UserResponse.model_validate(user)
@router.get("/{user_id}", response_model=UserResponse)
async def get_user(user_id: int, db: Session = Depends(get_db)):
user = await db.get_user(user_id)
if not user:
raise HTTPException(status.HTTP_404_NOT_FOUND, "User not found")
return UserResponse.model_validate(user)
const router = express.Router();
// POST /users
router.post('/', validateBody(createUserSchema), async (req, res, next) => {
try {
const existing = await User.findByEmail(req.body.email);
if (existing) {
return res.status(409).json({
error: { code: 'CONFLICT', message: 'Email already registered' }
});
}
const user = await User.create(req.body);
res.status(201).location(`/users/${user.id}`).json(toUserResponse(user));
} catch (err) {
next(err);
}
});
// GET /users/:id
router.get('/:id', async (req, res, next) => {
try {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({
error: { code: 'NOT_FOUND', message: 'User not found' }
});
}
res.json(toUserResponse(user));
} catch (err) {
next(err);
}
});
// Consistent error shape helper
function toErrorResponse(code, message, details = []) {
return { error: { code, message, details } };
}
</language_examples>
<success_criteria> API design reviewed or created with consistent resource naming, correct HTTP semantics, uniform error handling, and proper input validation at all boundaries. </success_criteria>
Promotes recurring feedback into the right skill, then guides /compact at phase boundaries.
Testing guidance for pytest, Jest/Vitest, Go, and TDD. Use when writing tests or improving coverage.
Methodical debugging with evidence and hypothesis testing. Use when troubleshooting fails or root cause is unclear.
Create new skills, commands, hooks, or subagents. Use when adding capabilities to Claude Code or Cursor.
PostgreSQL patterns for queries, schema, indexing, security. Use when writing SQL, designing schema, or adding indexes.
Reviews a GitHub PR diff for correctness, security, tests, architecture. Use when asked to review a PR or pull request.