REST API基础:HTTP请求方法、请求头与参数、状态码解读、限频机制

各位同学好,我是你们的讲师。今天咱们来聊聊REST API的基础。说实话,这部分内容看似简单,但我在对接几十家交易所的过程中,发现很多坑都埋在这些基础细节里。你想想看,如果连GET和POST都搞混了,那后面的策略跑起来可就要出大问题了。

一、HTTP请求方法:GET、POST、DELETE

交易所的REST API,说白了就是通过HTTP协议跟服务器打交道。常用的方法就三个:GET、POST、DELETE。我个人习惯把它们比作“查、改、删”。

1. GET请求:查数据

GET用于获取资源,比如查询行情、账户余额。它不会修改服务器上的任何数据。我在项目中遇到过,有人用GET请求去下单,结果服务器直接返回405错误——方法不被允许。

# 查询BTC/USDT的最新行情
GET https://api.exchange.com/v1/ticker?symbol=BTCUSDT

# 查询账户余额
GET https://api.exchange.com/v1/account/balance

注意:GET请求的参数都放在URL里,所以有长度限制。一般不超过2048个字符。如果你要传大量数据,那就得用POST了。

2. POST请求:改数据

POST用于创建或修改资源。下单、撤单、修改订单都用它。POST请求的参数通常放在请求体(body)里,而不是URL中。

# 提交一个限价买单
POST https://api.exchange.com/v1/order
Content-Type: application/json

{
    "symbol": "BTCUSDT",
    "side": "buy",
    "type": "limit",
    "price": "50000.00",
    "quantity": "0.01"
}

嗯,这里要注意:POST请求的body格式,交易所一般支持JSON和表单两种。我个人建议统一用JSON,因为可读性好,而且嵌套结构也方便。

3. DELETE请求:删数据

DELETE用于删除资源。在交易所场景里,最常用的就是撤销订单。

# 撤销指定订单
DELETE https://api.exchange.com/v1/order/123456789

我曾经犯过一个低级错误:用GET请求去撤单,结果查了半天才发现方法用错了。所以大家一定要记住:GET查、POST改、DELETE删,这个口诀很管用。

二、请求头与参数

请求头(Headers)和参数(Parameters)是API调用的“身份证”和“说明书”。少了它们,服务器根本不知道你是谁、想干什么。

1. 常见的请求头

请求头 说明 示例
Content-Type 请求体的格式 application/json
X-MBX-APIKEY API密钥(币安风格) abc123def456
Authorization 认证信息(Bearer Token) Bearer eyJhbGciOiJIUzI1NiJ9...
User-Agent 客户端标识 MyTradingBot/1.0

我个人习惯在请求头里加上User-Agent,这样服务器出问题时,对方能快速定位到我的请求。避坑指南:千万不要把API密钥放在URL里,我曾经见过有人把密钥写在GET请求的参数中,结果日志一打印,密钥全暴露了。

2. 参数传递方式

参数分三种:路径参数、查询参数、请求体参数。

  • 路径参数:直接写在URL路径里,比如 /order/123456 中的 123456 就是订单ID。
  • 查询参数:跟在URL问号后面,比如 ?symbol=BTCUSDT&limit=10
  • 请求体参数:放在POST请求的body里,JSON格式最常用。
# 路径参数示例
GET https://api.exchange.com/v1/order/123456

# 查询参数示例
GET https://api.exchange.com/v1/kline?symbol=BTCUSDT&interval=1h&limit=100

# 请求体参数示例
POST https://api.exchange.com/v1/order
{
    "symbol": "BTCUSDT",
    "side": "sell",
    "type": "market",
    "quantity": "0.1"
}

三、状态码解读

状态码是服务器给你的“回执”。读懂它,你就能快速定位问题。我刚开始做量化时,看到4xx就慌,后来发现其实每个状态码都有明确的含义。

1. 常见的状态码

状态码 含义 常见场景
200 请求成功 查询行情、下单成功
201 创建成功 订单提交成功(部分交易所用)
400 请求参数错误 缺少必填参数、参数格式不对
401 未授权 API密钥无效或过期
403 禁止访问 IP白名单限制、账户被冻结
404 资源不存在 查询不存在的订单ID
429 请求过于频繁 触发了限频机制
5xx 服务器错误 交易所内部故障

重点:状态码429是限频的标志。遇到它,你需要暂停请求,等待一段时间再重试。我见过有人不处理429,结果被交易所封了IP。

2. 如何处理状态码

写代码时,一定要对状态码做分类处理。我的做法是:

def handle_response(response):
    if response.status_code == 200:
        return response.json()
    elif response.status_code == 429:
        # 等待后重试
        time.sleep(5)
        return retry_request()
    elif response.status_code in [400, 401, 403]:
        # 记录日志,停止重试
        log.error(f"请求失败: {response.status_code} - {response.text}")
        raise APIError(response.status_code, response.text)
    else:
        # 5xx错误,可以重试
        time.sleep(1)
        return retry_request()

四、限频机制

限频(Rate Limit)是交易所保护自己的手段。说白了,就是防止你一个人把服务器打爆。每家交易所的限频规则都不一样,但核心逻辑是相通的。

1. 常见的限频方式

  • 基于IP的限频:每个IP地址每分钟最多N次请求。
  • 基于API Key的限频:每个API密钥每分钟最多M次请求。
  • 基于端口的限频:不同接口有不同的限制,比如行情接口宽松,下单接口严格。

我记得有一次对接某交易所,它的限频规则特别复杂:每秒钟最多10次请求,每分钟最多600次,而且下单接口的权重是普通接口的5倍。如果不仔细看文档,很容易被限。

2. 如何应对限频

我的经验是:永远假设自己会被限频。在代码里做好重试和退避机制。

import time
import requests

class RateLimiter:
    def __init__(self, max_calls=10, period=1.0):
        self.max_calls = max_calls
        self.period = period
        self.calls = []
    
    def wait_if_needed(self):
        now = time.time()
        # 移除过期的记录
        self.calls = [t for t in self.calls if now - t < self.period]
        if len(self.calls) >= self.max_calls:
            sleep_time = self.calls[0] + self.period - now
            if sleep_time > 0:
                time.sleep(sleep_time)
        self.calls.append(time.time())

# 使用示例
limiter = RateLimiter(max_calls=5, period=1.0)
for i in range(10):
    limiter.wait_if_needed()
    response = requests.get("https://api.exchange.com/v1/ticker?symbol=BTCUSDT")
    print(f"请求 {i+1}: {response.status_code}")

小技巧:很多交易所会在响应头里返回限频信息,比如 X-MBX-USED-WEIGHT(已用权重)和 X-MBX-ORDER-COUNT(订单计数)。你可以读取这些值,动态调整请求频率。

五、知识体系总览

下面这张图,是我自己整理的REST API基础知识结构。你可以把它当作一个“地图”,随时回来查阅。

REST API 基础 HTTP请求方法 GET - 查询数据 POST - 创建/修改 DELETE - 删除资源 请求头与参数 Content-Type / API Key 路径参数 / 查询参数 请求体参数 (JSON) 状态码解读 2xx - 成功 4xx - 客户端错误 5xx - 服务器错误 限频机制 IP限频 / API Key限频 退避重试 / 权重计算

这张图把四个核心知识点串在了一起。你想想看,每次调用API,其实就是在跟这四个部分打交道:选对方法、带好参数、看懂状态码、控制频率。缺一个,你的程序就可能出问题。

避坑指南:我曾经在对接某交易所时,没有仔细看限频文档,结果用单线程每秒发了100次请求。不到10秒,IP就被封了24小时。后来我学乖了,每次对接新交易所,第一件事就是读限频文档,然后在代码里加上限频器。

好了,这一章的内容就到这里。记住:基础不牢,地动山摇。REST API的这些基础,是你后续学习WebSocket、FIX协议、以及多交易所适配的基石。多动手写代码,多踩坑,你才能真正掌握它们。


专注资料整理