接口是服务之间的契约

一个微服务写好接口,几十个调用方在背后用。你随手改个字段名,可能第二天半夜就有线上告警。API 之所以重要,是因为它不是你一个人的代码,而是你和所有调用方之间的一份承诺。

好的 API 设计,让调用方用得顺、提供方改得动;坏的 API,则会在每一次迭代里反复制造线上事故。

改接口的代价,从来不只在你这一行——它要算上所有调用方跟着改的成本。
本文核心知识点
  • 契约接口是双方共同遵守的承诺。
  • 资源建模用名词表达资源,用动词表达操作。
  • 契约文档让双方有共同依据。
  • 版本演进时不破坏老调用方。
  • 向后兼容新增字段是安全的,删改字段是危险的。
API 设计示意:蓝色渐变背景两台发光笔记本服务模块,中间用发光双向箭头连接并流动光点,上方悬浮发光钥匙,右侧悬浮发光契约文档卡片,扁平科技插画
接口是两边之间的双向通道,契约就是让这条通道两边都心里有数。

先想清楚:这个接口到底干什么

设计接口最忌讳边写边想。动手之前先回答几个问题:这个接口给谁用?输入什么、输出什么?失败时调用方该怎么办?

要想清楚为什么
调用方是谁不同调用方需要的字段不同
核心输入输出避免接口越做越胖
失败语义调用方需要知道怎么处理错误
性能预期同步还是异步、要不要分页

把这些想清楚,接口的形状自然就出来了,而不是写着写着变成什么都往里塞的大杂烩。

资源建模:用名词而非动词

一套直观的约定是:路径表达资源(名词),方法表达操作(动词)。这样看到路径就知道操作的是什么,看到方法就知道要做什么。

# 资源用名词,操作用方法
GET    /orders          查订单列表
POST   /orders          创建订单
GET    /orders/{id}     查单个订单
PUT    /orders/{id}     更新订单
DELETE /orders/{id}     删除订单
# 不要把动作塞进路径里,读起来会很别扭。

路径保持简洁一致,调用方不用记一堆命名不一的接口,猜都能猜个八九不离十。

契约:让双方有共同依据

接口一旦被别人用,就得有一份双方都认的说明:参数有哪些、类型是什么、哪些必填、返回长什么样、错误码什么意思。

契约里该写清例子
请求参数字段名、类型、是否必填
响应结构成功返回什么、分页怎么给
错误码每种错误对应什么含义
版本与变更这次改动影响谁

契约最好能被工具自动校验,避免「文档写一套、实际跑一套」的对不上。