AI应用的API设计:RESTful与GraphQL的选择
前言
我们在设计产品 API 时,团队产生了分歧:一部分人认为应该用 RESTful,简单直观;另一部分人认为 GraphQL 更灵活,能减少请求次数。
最后我们选择了混合策略。今天,分享我们的思考和实践。
一、RESTful vs GraphQL
1.1 核心对比
| 维度 | RESTful | GraphQL |
|---|---|---|
| 数据获取 | 固定端点,返回固定数据 | 按需获取,灵活查询 |
| 请求次数 | 可能多次请求 | 一次请求获取所有数据 |
| 版本控制 | 通过 URL 版本化 | 无需版本化 |
| 缓存 | 天然支持 HTTP 缓存 | 需要自定义缓存策略 |
| 复杂度 | 低 | 高 |
1.2 适用场景
python
class APIChoice:
def recommend(self, scenario: str) -> str:
"""推荐 API 类型"""
scenarios = {
"mobile_app": "GraphQL",
"internal_tools": "RESTful",
"third_party_integration": "RESTful",
"complex_data_requirements": "GraphQL"
}
return scenarios.get(scenario, "RESTful")
二、RESTful 最佳实践
2.1 资源设计
python
class RESTResource:
def design(self, resource_name: str) -> dict:
"""设计 REST 资源"""
return {
"resource": resource_name,
"endpoints": {
"list": {"method": "GET", "path": f"/{resource_name}"},
"create": {"method": "POST", "path": f"/{resource_name}"},
"detail": {"method": "GET", "path": f"/{resource_name}/{{id}}"},
"update": {"method": "PUT", "path": f"/{resource_name}/{{id}}"},
"delete": {"method": "DELETE", "path": f"/{resource_name}/{{id}}"}
}
}
2.2 响应格式
python
class RESTResponse:
def format(self, data: dict, status: int = 200) -> dict:
"""格式化响应"""
return {
"status": status,
"data": data,
"metadata": {
"timestamp": datetime.now().isoformat(),
"version": "1.0"
}
}
三、GraphQL 实践
3.1 Schema 设计
python
class GraphQLSchema:
def generate(self) -> str:
"""生成 GraphQL Schema"""
return """
type Query {
user(id: ID!): User
users(limit: Int, offset: Int): [User]
}
type Mutation {
createUser(input: CreateUserInput!): User
}
type User {
id: ID!
name: String!
email: String!
createdAt: String!
}
input CreateUserInput {
name: String!
email: String!
}
"""
3.2 Resolver 实现
python
class GraphQLResolver:
def resolve_user(self, info, id: str) -> dict:
"""解析用户查询"""
return {
"id": id,
"name": "John",
"email": "john@example.com",
"createdAt": datetime.now().isoformat()
}
四、混合策略
4.1 策略选择
python
class HybridStrategy:
def __init__(self):
self.strategy = {
"public_api": "RESTful",
"mobile_app_api": "GraphQL",
"internal_api": "GraphQL"
}
def route(self, client_type: str) -> str:
"""路由到合适的 API"""
return self.strategy.get(client_type, "RESTful")
4.2 网关设计
python
class APIGateway:
def route_request(self, path: str, method: str) -> dict:
"""路由请求"""
if path.startswith("/graphql"):
return {"type": "graphql", "handler": "graphql_handler"}
else:
return {"type": "rest", "handler": "rest_handler"}
五、最佳实践
5.1 API 设计原则
- ✅ 一致性:保持接口风格一致
- ✅ 版本控制:清晰的版本管理
- ✅ 错误处理:统一的错误格式
- ✅ 文档完善:自动生成 API 文档
5.2 性能优化
- ✅ 请求合并:减少网络往返
- ✅ 缓存策略:合理利用缓存
- ✅ 批量操作:支持批量处理
- ✅ 分页查询:避免一次性返回大量数据
六、总结
API 设计需要根据场景选择。关键在于:
- 理解需求:根据客户端需求选择
- 保持简单:不要过度设计
- 灵活演进:预留扩展空间
- 文档驱动:API 即文档
记住:好的 API 应该是自解释的。