用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/boshi-xixixi/TraeSkill --skill api-design-principles命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | api-design-principles |
| description | 当用户需要设计新的 REST/GraphQL API、审查 API 规范或建立团队 API 设计标准时使用。此 Skill 提供直观的、可扩展的、可维护的 API 设计原则和最佳实践。 |
Master REST and GraphQL API design principles to build intuitive, scalable, and maintainable APIs that delight developers and stand the test of time.
mcp-feedback-enhanced tool (e.g., ask_followup_question) if available to ask clarifying questions or present design options for review. If not available, use standard chat.Resource-Oriented Architecture
HTTP Methods Semantics:
GET: Retrieve resources (idempotent, safe)POST: Create new resourcesPUT: Replace entire resource (idempotent)PATCH: Partial resource updatesDELETE: Remove resources (idempotent)Schema-First Development
Query Structure:
URL Versioning:
/api/v1/users
/api/v2/users
Header Versioning:
Accept: application/vnd.api+json; version=1
Query Parameter Versioning:
/api/users?version=1
# Good: Resource-oriented endpoints
GET /api/users # List users (with pagination)
POST /api/users # Create user
GET /api/users/{id} # Get specific user
PUT /api/users/{id} # Replace user
PATCH /api/users/{id} # Update user fields
DELETE /api/users/{id} # Delete user
# Nested resources
GET /api/users/{id}/orders # Get user's orders
POST /api/users/{id}/orders # Create order for user
# Bad: Action-oriented endpoints (avoid)
POST /api/createUser
POST /api/getUserById
POST /api/deleteUser
from typing import List, Optional
from pydantic import BaseModel, Field
class PaginationParams(BaseModel):
page: int = Field(1, ge=1, description="Page number")
page_size: int = Field(20, ge=1, le=100, description="Items per page")
class FilterParams(BaseModel):
status: Optional[str] = None
created_after: Optional[str] = None
search: Optional[str] = None
class PaginatedResponse(BaseModel):
items: List[dict]
total: int
page: int
page_size: int
pages: int
@property
def has_next(self) -> bool:
return self.page < self.pages
@property
def has_prev(self) -> :
.page >
fastapi FastAPI, Query, Depends
app = FastAPI()
():
query = build_query(status=status, search=search)
total = count_users(query)
offset = (page - ) * page_size
users = fetch_users(query, limit=page_size, offset=offset)
PaginatedResponse(
items=users,
total=total,
page=page,
page_size=page_size,
pages=(total + page_size - ) // page_size
)
from fastapi import HTTPException, status
from pydantic import BaseModel
class ErrorResponse(BaseModel):
error: str
message: str
details: Optional[dict] = None
timestamp: str
path: str
class ValidationErrorDetail(BaseModel):
field: str
message: str
value: Any
# Consistent error responses
STATUS_CODES = {
"success": 200,
"created": 201,
"no_content": 204,
"bad_request": 400,
"unauthorized": 401,
"forbidden": 403,
"not_found": 404,
"conflict": 409,
"unprocessable": 422,
"internal_error": 500
}
def raise_not_found(resource: str, id: str):
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail={
"error": "NotFound",
: ,
: {: }
}
)
():
HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail={
: ,
: ,
: {: [e.() e errors]}
}
)
():
user = fetch_user(user_id)
user:
raise_not_found(, user_id)
user
class UserResponse(BaseModel):
id: str
name: str
email: str
_links: dict
@classmethod
def from_user(cls, user: User, base_url: str):
return cls(
id=user.id,
name=user.name,
email=user.email,
_links={
"self": {"href": f"{base_url}/api/users/{user.id}"},
"orders": {"href": f"{base_url}/api/users/{user.id}/orders"},
"update": {
"href": f"{base_url}/api/users/{user.id}",
"method": "PATCH"
},
"delete": {
"href": f"{base_url}/api/users/{user.id}",
"method": "DELETE"
}
}
)
# schema.graphql
# Clear type definitions
type User {
id: ID!
email: String!
name: String!
createdAt: DateTime!
# Relationships
orders(first: Int = 20, after: String, status: OrderStatus): OrderConnection!
profile: UserProfile
}
type Order {
id: ID!
status: OrderStatus!
total: Money!
items: [OrderItem!]!
createdAt: DateTime!
# Back-reference
user: User!
OrderConnection
OrderEdge
PageInfo
Int
OrderEdge
Order
String
PageInfo
Boolean
Boolean
String
String
OrderStatus
PENDING
CONFIRMED
SHIPPED
DELIVERED
CANCELLED
DateTime
Money
user ID User
users Int , String, String UserConnection
order ID Order
createUser CreateUserInput CreateUserPayload
updateUser UpdateUserInput UpdateUserPayload
deleteUser ID DeleteUserPayload
createOrder CreateOrderInput CreateOrderPayload
CreateUserInput
String
String
String
CreateUserPayload
User
Error
Error
String
String
from typing import Optional, List
from ariadne import QueryType, MutationType, ObjectType
from dataclasses import dataclass
query = QueryType()
mutation = MutationType()
user_type = ObjectType("User")
@query.field("user")
async def resolve_user(obj, info, id: str) -> Optional[dict]:
"""Resolve single user by ID."""
return await fetch_user_by_id(id)
@query.field("users")
async def resolve_users(
obj,
info,
first: int = 20,
after: Optional[str] = None,
search: Optional[str] = None
) -> dict:
"""Resolve paginated user list."""
# Decode cursor
offset = decode_cursor(after) if after else 0
# Fetch users
users = await fetch_users(
limit=first + 1, # Fetch one extra to check hasNextPage
offset=offset,
search=search
)
# Pagination
has_next = (users) > first
has_next:
users = users[:first]
edges = [
{
: user,
: encode_cursor(offset + i)
}
i, user (users)
]
{
: edges,
: {
: has_next,
: offset > ,
: edges[][] edges ,
: edges[-][] edges
},
: count_users(search=search)
}
() -> :
loader = info.context[][]
orders = loader.load(user[])
paginate_orders(orders, first)
() -> :
:
validate_user_input()
user = create_user(
email=[],
name=[],
password=hash_password([])
)
{
: user,
: []
}
ValidationError e:
{
: ,
: [{: e.field, : e.message}]
}
from aiodataloader import DataLoader
from typing import List, Optional
class UserLoader(DataLoader):
"""Batch load users by ID."""
async def batch_load_fn(self, user_ids: List[str]) -> List[Optional[dict]]:
"""Load multiple users in single query."""
users = await fetch_users_by_ids(user_ids)
# Map results back to input order
user_map = {user["id"]: user for user in users}
return [user_map.get(user_id) for user_id in user_ids]
class OrdersByUserLoader(DataLoader):
"""Batch load orders by user ID."""
async def batch_load_fn(self, user_ids: List[str]) -> List[List[dict]]:
"""Load orders for multiple users in single query."""
orders = await fetch_orders_by_user_ids(user_ids)
# Group orders by user_id
orders_by_user = {}
for order in orders:
user_id = order["user_id"]
user_id orders_by_user:
orders_by_user[user_id] = []
orders_by_user[user_id].append(order)
[orders_by_user.get(user_id, []) user_id user_ids]
():
{
: {
: UserLoader(),
: OrdersByUserLoader()
}
}
/users, not /user)@deprecated directive for gradual migration当用户需要创建新 Skill 或更新现有 Skill 时使用。此 Skill 提供技能创建的完整工作流指导,包括需求分析、编写规范、工程化构建、质量评估和迭代优化。
当用户需要将需求转化为可执行任务、进行技术选型或协调多个专业 Skill 协作时使用。此 Skill 充当任务调度中心,接收需求文档并智能路由到合适的专业领域。
当用户需要从零开始构建完整项目或需要多角色协作时使用。此 Skill 充当全能开发团队,包含产品经理、架构师、设计师、开发者和测试人员,指导从想法到上线的全过程。
基于 SOC 职业分类