开放API怎么设计?

wen python案例 1

本文目录导读:

开放API怎么设计?

  1. 核心设计原则
  2. 接口风格与协议选择
  3. URL与资源设计
  4. 请求与响应规范
  5. 安全与认证
  6. 错误码设计
  7. 版本管理
  8. 文档与工具
  9. 一个完整的API设计示例
  10. 进阶实践:GraphQL
  11. 总结:优秀API Checklist

设计一个优秀的开放API需要兼顾易用性稳定性安全性可扩展性,下面是一个从零到一的系统性设计指南,涵盖了从HTTP规范到文档、SDK的完整流程。

核心设计原则

  1. 面向资源设计:把API看作对资源的操作,而不是RPC(远程过程调用)。
  2. 一致性:URL路径、请求/响应格式、错误码、分页方式都保持一致。
  3. 版本控制:保证向后兼容,允许API平滑演进。
  4. 无状态:每个请求都包含所有必要信息,服务器的会话状态不依赖客户端。
  5. 安全第一:认证、授权、限流、数据校验。

接口风格与协议选择

目前主流的选择是 RESTful API,对于复杂、强类型、高数据交互的场景(如内部微服务、给前端用的复杂查询)推荐 GraphQL,对于低延迟、高频次场景(如实时聊天、游戏数据同步)选择 WebSocket

特性 RESTful GraphQL WebSocket
数据获取 服务端定义返回结构 客户端精确查询所需字段 双向流式推送
缓存 天然支持HTTP缓存 缓存复杂,需要客户端处理 不适用
版本管理 URL (/v1/) 或 Header 无需版本,通过Schema演进 协议协商
典型场景 标准业务CRUD、公开API 复杂数据仪表盘、移动端 实时通知、直播、协同编辑

URL与资源设计

遵循RESTful规范,使用名词复数表示资源,用HTTP动词表示操作。

正确姿势

  • GET /api/v1/users 获取用户列表
  • GET /api/v1/users/{id} 获取单个用户
  • POST /api/v1/users 创建用户
  • PUT /api/v1/users/{id} 完整更新用户
  • PATCH /api/v1/users/{id} 局部更新用户
  • DELETE /api/v1/users/{id} 删除用户

复杂关系与操作

  • 关联资源GET /api/v1/users/{id}/orders (获取用户的订单)
  • 标准操作POST /api/v1/users/{id}/activate (激活用户,用动词表示动作)
  • 搜索GET /api/v1/orders?status=paid&page=1&size=20
  • 字段筛选GET /api/v1/users?fields=id,name,email

常见错误设计

  • GET /api/getUsers (动词在URL中)
  • POST /api/deleteUser (删除用了POST)
  • GET /api/v1/usersAPI (混合术语)

请求与响应规范

统一响应格式

使用统一的JSON结构包裹数据,方便客户端统一解析。

成功响应 (HTTP 2xx)

{
  "code": 0,
  "message": "success",
  "data": { 
    "id": 123,
    "name": "张三",
    "email": "zhangsan@example.com"
  }
}

列表响应(带分页)

{
  "code": 0,
  "message": "success",
  "data": {
    "items": [ ... ],
    "pagination": {
      "page": 1,
      "size": 20,
      "total": 100,
      "total_pages": 5
    }
  }
}

错误响应 (HTTP 4xx/5xx)

{
  "code": 1001,
  "message": "参数校验失败",
  "errors": [
    { "field": "email", "message": "邮箱格式不正确" }
  ]
}

HTTP状态码使用指南

状态码 含义 使用场景
200 OK 请求成功
201 Created 资源创建成功(POST)
204 No Content 删除/更新成功,无返回体(DELETE/PUT)
301/302 Redirect 资源地址变更
400 Bad Request 客户端参数错误、校验失败
401 Unauthorized 未认证(缺少Token或Token过期)
403 Forbidden 已认证但无权限
404 Not Found 资源不存在
409 Conflict 资源冲突(如重复创建、版本冲突)
422 Unprocessable Entity 语义错误(如业务逻辑校验失败)
429 Too Many Requests 限流触发
500 Internal Server Error 服务端未捕获的异常

安全与认证

认证方案

  • API Key:简单易用,通过Header X-API-Key 或Query参数传递,适合低安全要求的公开数据。
  • JWT (JSON Web Token):最常用、无状态的认证方式,服务端签发Token,客户端每次请求在Authorization: Bearer <token>中携带。
  • OAuth 2.0:用于“授权第三方应用访问用户数据”,支持授权码、客户端凭证、隐式授权等模式,公开API强烈建议使用。

常见安全措施

  • HTTPS强制:所有API必须通过TLS加密。
  • 限流 (Rate Limiting):通过Header返回剩余配额。
    • X-RateLimit-Limit: 100
    • X-RateLimit-Remaining: 99
    • X-RateLimit-Reset: 1626123456
  • 输入校验:服务端对所有参数进行白名单校验,防止SQL注入、XSS攻击。
  • CORS配置:开放给前端调用时,正确配置Access-Control-Allow-Origin
  • 敏感数据脱敏:返回数据时,对密码、手机号、身份证等做掩码处理。

错误码设计

使用业务错误码(4-5位数字)而非HTTP状态码直接替代,因为HTTP状态码有限,不足以表达细粒度的业务错误。

# 通用错误
1000: 系统内部错误
1001: 参数校验失败
# 认证授权
2001: Token无效或过期
2002: 无权限操作
# 业务错误 (以订单模块为例)
3001: 订单不存在
3002: 订单已支付,无法取消
3003: 库存不足

版本管理

明确的版本号是API演进的基石。

  • 推荐方式:URL路径版本号 https://api.example.com/v1/orders
  • 备选方式:自定义Header Accept: application/vnd.example.v1+json

文档与工具

API设计出来,没人会用等于白费,推荐使用OpenAPI规范(原Swagger)来描述API。

  • 工具选择
    • Swagger UI:自动生成交互式文档,开发者可以在线调试。
    • Stoplight:更现代、协作性强的API设计平台。
    • Postman:提供集成的文档发布和测试环境。

文档必须包含的内容

  1. 基础URL版本号
  2. 认证方式(如何获取和传递Token)。
  3. 每个接口的:方法、URL、请求参数(Query/Header/Body)、响应示例、错误码。
  4. 限流策略
  5. 代码示例(至少提供curl、Python、JavaScript)。

一个完整的API设计示例

假设我们要设计一个“用户订单管理”API的 /v1/orders 接口:

基础URL: https://api.example.com/v1
认证: Bearer Token in Authorization Header

创建订单

  • POST /orders
  • Request Body:
    {
      "product_id": "prod_123",
      "quantity": 2,
      "shipping_address": "北京市朝阳区..."
    }
  • Response (201):
    {
      "code": 0,
      "message": "success",
      "data": {
        "order_id": "ord_456",
        "status": "pending",
        "total_price": 199.98,
        "created_at": "2023-10-27T10:00:00Z"
      }
    }

查询订单列表

  • GET /orders?status=paid&page=1&size=20
  • Response (200):
    {
      "code": 0,
      "message": "success",
      "data": {
        "items": [ { ... } ],
        "pagination": { "page": 1, "size": 20, "total": 50 }
      }
    }

进阶实践:GraphQL

如果你选择GraphQL,设计思路会变成:定义Schema -> 实现Resolver -> 客户端按需查询,它的核心优势是避免了冗余数据和多个请求的拼接

// 客户端只需这样查询,就能一次性获得用户、订单、商品信息
{
  user(id: "123") {
    name
    orders {
      id
      total
      items {
        product {
          name
          price
        }
      }
    }
  }
}

优秀API Checklist

  • [ ] 符合直觉:URL、动词、参数命名清晰易懂。
  • [ ] 一致性强:所有接口遵守相同规范。
  • [ ] 健壮:有完善的错误处理、限流、安全加密。
  • [ ] 有文档:自动生成、随时更新的交互式文档。
  • [ ] 可测试:提供沙箱环境、Mock数据或测试Key。

设计API时,可以时刻换位思考:“如果我是一个刚接触这个API的新手,我能不看文档就猜出这个接口怎么用吗?” 如果能,那就算成功了。

抱歉,评论功能暂时关闭!