3. REST API深度实践:请求构造与响应处理

说实话,REST API 这东西,看着简单,用起来全是坑。我见过太多人把 GET 和 POST 搞混,也见过不少团队因为请求头少写一个字段,导致整个交易系统崩了半小时。今天咱们就把这块彻底掰开揉碎,讲清楚。

3.1 请求构造:GET / POST / DELETE

交易所的 REST API,说白了就是三种操作:查、改、删。对应到 HTTP 方法上,就是 GET、POST、DELETE。

GET 请求

用来获取数据。比如查账户余额、查订单状态、查行情。我个人习惯,所有只读操作都用 GET。

# 获取账户信息
GET /api/v2/account

# 获取订单详情
GET /api/v2/order?orderId=123456

注意:GET 请求的参数必须放在 URL 里。别把敏感信息放进去,比如 API Key。嗯,这里有个坑——有些交易所会把参数放在请求体里,但 HTTP 规范明确说了,GET 请求的 body 可能被中间件丢弃。我踩过这个坑,后来统一用 URL 参数。

POST 请求

用来创建资源。比如下单、撤单、修改订单。POST 请求的参数通常放在请求体里,用 JSON 格式。

POST /api/v2/order
Content-Type: application/json

{
    "symbol": "BTCUSDT",
    "side": "BUY",
    "type": "LIMIT",
    "price": "50000.00",
    "quantity": "0.01"
}

你想想看,为什么不用 GET 来下单?因为 GET 请求会被浏览器缓存,万一用户刷新页面,订单就重复提交了。POST 请求不会缓存,安全得多。

DELETE 请求

用来删除资源。比如取消订单、删除监听。DELETE 请求的参数可以放 URL,也可以放 body,看交易所的规范。

# 取消订单
DELETE /api/v2/order?orderId=123456

# 或者
DELETE /api/v2/order
{
    "orderId": "123456"
}

我在项目中遇到过,有些交易所的 DELETE 请求不支持 body 传参,只能用 URL。所以对接前一定要看文档,别想当然。

3.2 请求头与参数规范

请求头是 API 的身份证。少了它,交易所根本不知道你是谁。

请求头 说明 示例
X-MBX-APIKEY API Key,标识身份 X-MBX-APIKEY: abc123
Content-Type 请求体格式 application/json
X-MBX-TIMESTAMP 请求时间戳(毫秒) 1700000000000
X-MBX-SIGNATURE 签名,验证请求合法性 sha256签名值

参数规范

  • 时间戳:必须用服务器时间,别用本地时间。我见过有人用本地时间,结果时区不对,请求全被拒了。
  • 签名:把参数按字母序排序,拼接成字符串,再用 HMAC-SHA256 加密。顺序错了,签名就无效。
  • 请求ID:有些交易所要求传一个唯一 ID,用来防重复提交。我习惯用 UUID。

核心原则:请求头里的每个字段,交易所都会校验。少一个,或者格式不对,直接返回 4xx 错误。

3.3 响应数据结构解析

交易所返回的数据,通常是 JSON 格式。结构很固定,但细节要注意。

{
    "code": 0,
    "msg": "success",
    "data": {
        "orderId": "123456",
        "symbol": "BTCUSDT",
        "status": "NEW",
        "price": "50000.00",
        "quantity": "0.01",
        "executedQty": "0.00",
        "cummulativeQuoteQty": "0.00"
    }
}

常见的字段:

  • code:状态码。0 表示成功,非 0 表示失败。
  • msg:提示信息。成功时是 "success",失败时是错误描述。
  • data:真正的数据。可能是对象,也可能是数组。

为什么有些交易所用 code 而不用 HTTP 状态码?说白了,HTTP 状态码只有几十个,不够用。交易所自己定义 code,可以更精细地描述错误。比如 1001 表示余额不足,1002 表示价格超出范围。

我的习惯:解析响应时,先检查 code,再解析 data。别直接拿 data 用,万一 code 不是 0,data 可能是 null。

3.4 常见 HTTP 状态码处理

HTTP 状态码是服务器给你的第一层反馈。我把它分成三类:

状态码 含义 处理方式
200 请求成功 正常解析响应
4xx 客户端错误 检查参数、签名、权限
5xx 服务器错误 重试,但别太频繁

常见的 4xx 错误

  • 400 Bad Request:参数格式不对。比如价格传了字符串 "abc"。
  • 401 Unauthorized:API Key 无效或签名错误。我遇到过,签名时忘了加时间戳。
  • 403 Forbidden:权限不足。比如只读 Key 尝试下单。
  • 429 Too Many Requests:请求太频繁。需要限速。

5xx 错误怎么处理?

我曾经遇到交易所 502 持续了 5 分钟。当时我的策略是:

  1. 第一次遇到 5xx,等 1 秒重试。
  2. 第二次,等 2 秒。
  3. 第三次,等 4 秒。
  4. 最多重试 5 次,超过就报警。

这叫指数退避。别一上来就疯狂重试,会把交易所打挂的。

警告:别把 4xx 错误当成 5xx 处理。4xx 是客户端的问题,重试一万次也没用。先检查代码,再重试。

3.5 知识体系总览

下面这张图,把 REST API 的核心流程串起来了。从请求构造到响应处理,每一步都有坑,每一步都要小心。

REST API 请求与响应流程 客户端 请求构造 GET / POST / DELETE 请求头与参数 API Key / 签名 / 时间戳 交易所 响应处理 解析 JSON / 检查 code 状态码处理 200 / 4xx / 5xx 核心流程:构造请求 → 添加请求头与参数 → 发送到交易所 → 解析响应 → 处理状态码 注意:4xx 错误不要重试,5xx 错误使用指数退避策略

这张图把整个流程串起来了。你从左边开始,构造请求,加上请求头和参数,发给交易所。交易所返回响应,你解析 JSON,检查状态码。每一步都有对应的处理逻辑。

好了,REST API 的深度实践就讲到这里。记住,对接交易所不是写个 HTTP 请求那么简单。请求头、签名、状态码处理,每一个细节都可能让你踩坑。多测试,多验证,别想当然。

专注资料整理