API 是软件之间的契约
API(Application Programming Interface)不是某段神秘代码,而是一份软件之间的交互契约。它规定调用方可以访问哪些地址、提交什么数据,以及服务方会返回怎样的结果。
把它理解成餐厅服务员很直观:菜单是接口文档,点单是请求,厨房是服务端,上菜是响应。顾客不需要进入厨房,但必须按照菜单提供的信息点单。
一个网络 API 通常由四部分组成:
| 要素 | 作用 | 示例 |
|---|---|---|
| 端点 | 定位资源 | /v1/users/42 |
| 方法 | 描述操作 | GET、POST、PATCH、DELETE |
| 请求 | 携带参数、请求头和正文 | JSON、查询参数、令牌 |
| 响应 | 返回状态、数据和错误信息 | 状态码、响应头、JSON |
API 的价值在于隔离实现。客户端只依赖公开契约,服务端可以更换数据库或重构内部代码,只要契约没有被破坏,调用方就不需要跟着重写。

HTTP 方法与状态码
REST API 通常用名词表示资源,用 HTTP 方法表达动作:
GET /v1/articles 获取文章列表
GET /v1/articles/42 获取一篇文章
POST /v1/articles 创建文章
PATCH /v1/articles/42 更新部分字段
DELETE /v1/articles/42 删除文章
状态码负责说明结果,而不是装饰:
2xx:请求成功,例如200 OK、201 Created400:请求格式或参数有误401:尚未通过身份认证403:身份有效,但没有操作权限404:目标资源不存在429:请求超过频率限制5xx:服务端处理失败
调用方不应只检查“有没有返回数据”,而应先判断状态码,再验证响应结构。
完成第一次可靠调用
下面使用公开测试接口读取一篇示例文章:
import requests
url = "https://jsonplaceholder.typicode.com/posts/1"
try:
response = requests.get(
url,
headers={"Accept": "application/json"},
timeout=10,
)
response.raise_for_status()
data = response.json()
title = data.get("title")
if not isinstance(title, str):
raise ValueError("响应中缺少有效的 title 字段")
print(title)
except requests.Timeout:
print("请求超时,请稍后重试")
except requests.HTTPError as error:
print(f"服务返回错误状态:{error.response.status_code}")
except (requests.RequestException, ValueError) as error:
print(f"调用失败:{error}")
这段代码比“发送请求后直接打印 JSON”多做了四件重要的事:
- 设置超时,避免程序无限等待
- 检查 HTTP 状态,避免把错误页面当成正常数据
- 验证关键字段,避免上游结构变化后静默产生错误
- 区分超时、HTTP 错误和数据错误,便于定位问题
认证信息不要写进代码
多数正式 API 使用密钥或访问令牌识别调用方:
import os
import requests
token = os.environ["SERVICE_API_TOKEN"]
response = requests.get(
"https://api.example.com/v1/profile",
headers={"Authorization": f"Bearer {token}"},
timeout=10,
)
response.raise_for_status()
密钥应保存在环境变量或专门的密钥管理服务中,不要提交到 Git 仓库、截图、日志或前端代码。前端网页中出现的密钥最终都会被用户读取;需要保密的调用应经过自己的后端。
认证和授权也不是一回事:401 通常表示“你是谁尚未确认”,403 表示“已经知道你是谁,但你不能执行这项操作”。
排错时按链路检查
| 现象 | 优先检查 |
|---|---|
| 无法连接或超时 | 地址、网络、代理、DNS、超时设置 |
400 | 参数名称、数据类型、JSON 格式 |
401 | 令牌是否存在、过期,请求头格式是否正确 |
403 | 账号权限、接口范围、IP 白名单 |
429 | 频率限制、并发量、退避重试策略 |
5xx | 服务状态、请求 ID、服务端日志 |
状态为 200 但程序报错 | 响应字段、数据类型、版本变化 |
调试时先用 curl 或 Postman 复现最小请求,再回到业务代码。这样可以快速判断问题位于接口本身、网络环境,还是程序的数据处理逻辑。
设计一个容易使用的 API
如果你是接口提供者,优质 API 通常具备以下特征:
- 资源命名稳定,方法语义一致
- 成功与失败都返回可预测的结构
- 错误信息包含机器可读的错误码和人可读的说明
- 列表接口支持分页、筛选和排序
- 可能重复提交的操作考虑幂等性
- 文档给出请求、响应和失败示例
- 通过版本号管理不兼容变更
在 Agent 场景中,这些要求更加重要。模型需要清晰的工具名称、严格的参数结构和可解释的错误结果。接口越模糊,Agent 越容易猜错;接口越稳定,自动化流程越可靠。
最小实践清单
第一次接入新 API 时,只需要完成以下闭环:
- 阅读端点、方法、认证和返回格式
- 用最小请求确认接口可用
- 设置超时并检查状态码
- 验证真正依赖的响应字段
- 对限流和临时故障采用有限次数的退避重试
- 确保密钥不会进入仓库和日志
理解 API 的关键不是背完所有状态码,而是建立边界意识:客户端按契约发送请求,服务端按契约返回结果,双方都要对失败情况做明确处理。掌握这个模型后,无论接入数据服务、支付系统还是 AI 能力,思路都是相通的。