بنقرة واحدة
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 المهني
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.
| 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>