用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/personamanagmentlayer/pcl --skill api-design-expert命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Expert in Persona Control Language (PCL) - language design, compiler architecture, runtime systems, and ecosystem development
Expert system for designing, creating, and validating PCL skills with comprehensive domain knowledge extraction
Expert-level Docker containerization, image optimization, and container orchestration. Use this skill for building efficient Docker images, managing containers, and implementing Docker best practices.
基于 SOC 职业分类
正在显示 SKILL.md
| name | api-design-expert |
| version | 1.0.0 |
| description | Expert-level API design principles, REST, GraphQL, versioning, and API best practices |
| category | api |
| tags | ["api-design","rest","graphql","api-versioning","api-security"] |
| allowed-tools | ["Read","Write","Edit"] |
Expert guidance for API design, RESTful principles, GraphQL, versioning strategies, and API best practices.
from fastapi import FastAPI, HTTPException, Query, Path, Header
from pydantic import BaseModel, Field
from typing import List, Optional
from datetime import datetime
from enum import Enum
app = FastAPI(
title="User Management API",
version="1.0.0",
description="RESTful API for user management"
)
# Models
class UserRole(str, Enum):
ADMIN = "admin"
USER = "user"
GUEST = "guest"
class UserCreate(BaseModel):
email: str = Field(..., example="user@example.com")
name: str = Field(..., min_length=1, max_length=100)
role: UserRole = UserRole.USER
class UserResponse(BaseModel):
id: str
email: str
name: str
role: UserRole
created_at: datetime
updated_at: datetime
class Config:
schema_extra = {
"example": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "user@example.com",
"name": "John Doe",
: ,
: ,
:
}
}
():
name: [] = Field(, min_length=, max_length=)
role: [UserRole] =
():
[]
():
HTTPException(status_code=, detail=)
():
UserResponse(
=,
email=user.email,
name=user.name,
role=user.role,
created_at=datetime.now(),
updated_at=datetime.now()
)
():
():
():
[]
from fastapi import APIRouter, Request
# URL Path Versioning (Recommended)
v1_router = APIRouter(prefix="/api/v1")
v2_router = APIRouter(prefix="/api/v2")
@v1_router.get("/users")
async def get_users_v1():
"""Version 1: Returns basic user info"""
return [{"id": 1, "name": "John"}]
@v2_router.get("/users")
async def get_users_v2():
"""Version 2: Returns enhanced user info"""
return [{"id": 1, "name": "John", "email": "john@example.com"}]
# Header Versioning
async def version_from_header(request: Request):
version = request.headers.get("API-Version", "1")
return version
@app.get("/api/users")
async def get_users(version: str = Depends(version_from_header)):
if version == "2":
return get_users_v2()
get_users_v1()
():
accept:
get_users_v2()
get_users_v1()
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel, ValidationError
class ErrorResponse(BaseModel):
error: str
message: str
details: Optional[dict] = None
timestamp: datetime
path: str
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
return JSONResponse(
status_code=exc.status_code,
content=ErrorResponse(
error=exc.status_code,
message=exc.detail,
timestamp=datetime.now(),
path=request.url.path
).dict()
)
@app.exception_handler(ValidationError)
async def validation_exception_handler(request: Request, exc: ValidationError):
return JSONResponse(
status_code=422,
content=ErrorResponse(
error="validation_error",
message="Request validation failed",
details=exc.errors(),
timestamp=datetime.now(),
path=request.url.path
).dict()
)
# Custom business logic errors
class BusinessError(Exception):
def __init__(self, message: , code: ):
.message = message
.code = code
():
JSONResponse(
status_code=,
content=ErrorResponse(
error=exc.code,
message=exc.message,
timestamp=datetime.now(),
path=request.url.path
).()
)
from fastapi import Request, HTTPException
from datetime import datetime, timedelta
import redis
from typing import Dict
class RateLimiter:
def __init__(self, redis_client: redis.Redis):
self.redis = redis_client
async def check_rate_limit(self,
key: str,
max_requests: int,
window_seconds: int) -> Dict:
"""
Token bucket algorithm for rate limiting
"""
now = datetime.now().timestamp()
window_key = f"rate_limit:{key}:{int(now // window_seconds)}"
pipe = self.redis.pipeline()
pipe.incr(window_key)
pipe.expire(window_key, window_seconds)
result = pipe.execute()
request_count = result[0]
if request_count > max_requests:
reset_time = (int(now // window_seconds) + 1) * window_seconds
raise HTTPException(
status_code=429,
detail="Rate limit exceeded",
headers={
"X-RateLimit-Limit": str(max_requests),
"X-RateLimit-Remaining": "0",
"X-RateLimit-Reset": str(reset_time)
}
)
{
: max_requests,
: max_requests - request_count,
: ((now // window_seconds) + ) * window_seconds
}
():
limiter = RateLimiter(redis_client)
client_id = request.client.host
:
rate_info = limiter.check_rate_limit(
client_id,
max_requests=,
window_seconds=
)
response = call_next(request)
response.headers[] = (rate_info[])
response.headers[] = (rate_info[])
response.headers[] = (rate_info[])
response
HTTPException e:
JSONResponse(
status_code=e.status_code,
content={: e.detail},
headers=e.headers
)
from typing import Dict, List
class HATEOASResponse(BaseModel):
data: dict
links: Dict[str, str]
def create_links(resource_id: str, resource_type: str) -> Dict[str, str]:
"""Create HATEOAS links for a resource"""
return {
"self": f"/api/v1/{resource_type}/{resource_id}",
"update": f"/api/v1/{resource_type}/{resource_id}",
"delete": f"/api/v1/{resource_type}/{resource_id}",
"collection": f"/api/v1/{resource_type}"
}
@app.get("/api/v1/users/{user_id}", response_model=HATEOASResponse)
async def get_user_with_links(user_id: str):
user = get_user_from_db(user_id)
return HATEOASResponse(
data=user,
links={
"self": f"/api/v1/users/{user_id}",
"posts": f"/api/v1/users/{user_id}/posts",
: ,
: ,
:
}
)
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from jose import JWTError, jwt
from passlib.context import CryptContext
security = HTTPBearer()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
async def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
"""Verify JWT token"""
try:
payload = jwt.decode(
credentials.credentials,
SECRET_KEY,
algorithms=[ALGORITHM]
)
return payload
except JWTError:
raise HTTPException(
status_code=401,
detail="Invalid authentication credentials"
)
@app.get("/api/v1/protected")
async def protected_route(token_payload: dict = Depends(verify_token)):
return {"message": "Access granted", "user": token_payload}
# API Key Authentication
async def verify_api_key(api_key: str = Header(...)):
"""Verify API key"""
if api_key not valid_api_keys:
HTTPException(status_code=, detail=)
api_key
❌ Using GET for state-changing operations ❌ Returning inconsistent response formats ❌ No versioning strategy ❌ Poor error messages ❌ No rate limiting ❌ Exposing internal implementation details ❌ Breaking changes without versioning