接口规范
提示
本文章部分内容引用 Apifox 中的 RESTful Web API 接口设计规范。
1. 使用良好的名称
为资源、属性、操作和参数赋予良好的名称对于打造卓越的开发者体验至关重要。
资源由名词描述。资源和属性的名称必须具有描述性且易于客户理解。应使用与用户场景(而非服务实现细节)相对应的名称,例如使用"Diagnosis"(诊断)而非"TreeLeafNode"(树叶子节点)。名称应传达值的目的,而非仅仅描述其结构,例如使用"ConfigurationSetting"(配置设置)而非"KeyValuePair"(键值对)。易于理解源于熟悉感和认知度;您应优先考虑产品门户/用户界面中的名称以及行业标准保持一致。
名称应帮助开发者发现功能,而无需频繁查阅文档。使用常见模式和标准约定有助于开发者正确猜测常见属性名称及其含义。使用详细的命名模式,并避免使用除服务领域中众所周知的缩写词之外的缩写。
✅ 务必尽可能对同一概念使用相同的名称,对不同概念使用不同的名称。
1.1 推荐的命名规范
以下是推荐命名规范:
✅ 务必将集合命名为复数名词或复数名词短语(使用正确的英语)。
✅ 务必将非集合的值命名为单数名词或单数名词短语。
☑️ 应在名称中将形容词置于名词之前(当名称同时包含名词和形容词时)。
例如:collectedItems(收集项),而非 itemsCollected(项收集)。
☑️ 应将所有首字母缩写词视为常规单词进行大小写处理(即采用 lower camelCase 驼峰命名法)。
例如:nextUrl,而非 nextURL。
☑️ 应在日期时间值的名称中使用"At"后缀。
例如:createdAt(创建于),而非 created(创建)或 createdDateTime(创建日期时间)。
☑️ 应对于具有明确度量单位的值(如字节、英里等),在名称中使用该度量单位的后缀。在适当情况下,使用普遍接受的单位缩写(例如,使用"Km"而非"Kilometers")。
☑️ 应对于时间持续时间使用 int 类型,并在名称中包含时间单位。
例如:使用 expirationDays(过期天数)作为 int 类型,而非使用 expiration(过期)作为 date-time 类型。
⚠️ 不应在资源或属性名称中使用品牌名称。
⚠️ 不应使用首字母缩写词或缩写,除非它们被广泛理解(例如,"ID" 或 "URL" 可以,但不应使用 "Num" 表示 "number")。
⚠️ 不应使用在广泛使用的编程语言(包括 C#、Java、JavaScript/TypeScript、Python、C++ 和 Go)中的保留字作为名称。
⛔ 禁止在布尔值的名称中使用"is"前缀,例如使用"enabled"(已启用),而非"isEnabled"(是否启用)。
⛔ 禁止在名称中使用冗余词语。
例如:/phones/number(电话/号码),而非 /phone/phoneNumber(电话/电话号码)。
2. HTTP 请求方法
HTTP 协议定义了许多请求方法,这些方法指示要在资源上执行的作。RESTful Web API 中使用的最常见方法是 GET、POST、PUT、PATCH 和 DELETE。每种方法对应特定操作。在设计 RESTful Web API 时,应以符合协议定义、访问资源以及执行动作的一致性进行使用这些方法。
请务必记住,特定请求方法的效果应取决于资源是集合还是单个项。下表包含大多数 RESTful 实现使用的一些约定。
2.1 HTTP 状态码
REST API 使用 HTTP 响应消息的 Status-Line 部分来通知客户端其请求的总体结果。RFC 2616 定义了 Status-Line 语法,如下所示:
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
HTTP 定义了四十个标准状态代码,可用于传达客户端请求的结果。状态代码分为以下五个类别。
| 类别 | 描述 |
|---|---|
| 1xx:信息 | 通信传输协议级信息。 |
| 2xx:成功 | 表示客户端的请求已成功接受。 |
| 3xx:重定向 | 表示客户端必须执行一些其他操作才能完成其请求。 |
| 4xx:客户端错误 | 此类错误状态代码指向客户端。 |
| 5xx:服务器错误 | 服务器负责这些错误状态代码。 |
200(OK)
它表示 REST API 成功执行了客户端请求的任何操作,并且 2xx 系列中没有更具体的代码是合适的。
与 204 状态代码不同,200 响应应包括响应主体。响应返回的信息取决于请求中使用的方法,例如:
- 在响应中发送 GET 对应于所请求资源的实体;
- HEAD 对应于所请求资源的实体头字段在响应中发送而没有任何消息体;
- POST 一个描述或包含行动结果的实体;
- 跟踪包含终端服务器接收的请求消息的实体。
201(创建)
只要在集合内创建资源,REST API 就会使用 201 状态代码进行响应。由于某些控制器动作,有时可能会创建新资源,在这种情况下,201 也是适当的响应。
新创建的资源可以由响应实体中返回的 URI 引用,其中由 Location 头字段给出的资源的最具体 URI。
原始服务器必须在返回 201 状态代码之前创建资源。如果无法立即执行操作,服务器应该响应 202(已接受)响应。
202(已接受)
202 响应通常用于需要很长时间才能处理的操作。它表示该请求已被接受处理,但处理尚未完成。该请求可能会或可能不会最终被执行,甚至可能在处理时不允许。
其目的是允许服务器接受对某些其他进程的请求(可能是每天只运行一次的面向批处理的进程),而不要求用户代理与服务器的连接持续到进程完成为止。
使用此响应返回的实体应该包括请求的当前状态的指示以及指向状态监视器的指针(作业队列位置)或某个用户 何时可以期望满足请求的估计。
204(无内容)
在 204 个状态的代码通常是响应发送到一个PUT,POST或DELETE当 REST API 拒绝发送回在响应消息的主体的任何状态消息或表示请求。
API 还可以结合 GET 请求发送 204 以指示所请求的资源存在,但是没有要包括在正文中的状态表示。
如果客户端是用户代理,它不应该从导致请求发送的文档视图中更改它的文档视图。此响应主要用于允许在不导致更改用户代理的活动文档视图的情况下进行操作的输入,尽管任何新的或更新的元信息应该应用于当前在用户代理的活动视图中的文档。
204 响应绝不能包含消息体,因此总是在头字段之后的第一个空行终止。
301(永久移动)
301 状态代码表示 REST API 的资源模型已经过重新设计,并且已为客户端请求的资源分配了新的永久 URI。REST API 应在响应的 Location 头中指定新的 URI,并且所有将来的请求都应该定向到给定的 URI。
您很难在 API 中使用此响应代码,因为您始终可以使用 API 版本控制新 API,同时保留旧 API。
302(找到)
HTTP 响应状态代码 302 Found 是执行 URL 重定向的常用方式。具有此状态代码的 HTTP 响应还将在位置标头字段中提供 URL。通过具有该代码的响应来邀请用户代理(例如,web 浏览器),以对位置字段中指定的新 URL 做出第二个(否则相同的)请求。
许多 Web 浏览器以违反此标准的方式实现此代码,将新请求的请求类型更改为 GET,而不管原始请求中使用的类型(例如 POST)。RFC 1945 和 RFC 2068 指定不允许客户端更改重定向请求上的方法。已经为希望明确清楚客户端期望哪种反应的服务器添加了状态代码 303 和 307。
303(见其他)
303 响应表示控制器资源已完成其工作,但它不是发送可能不需要的响应主体,而是向客户端发送响应资源的 URI。这可以是临时状态消息的 URI,也可以是某些已存在的,更永久的资源的 URI。
一般而言,303 状态代码允许 REST API 发送对资源的引用,而不强制客户端下载其状态。相反,客户端可以向 Location 头的值发送 GET 请求。
303 响应绝不能被缓存,但对第二个(重定向)请求的响应可能是可缓存的。
304(未修改)
此状态代码类似于 204(“无内容”),因为响应正文必须为空。关键的区别在于,当在正文中没有要发送的内容时使用 204,而在自请求头 If-Modified-Since 或 If-None-Match 指定的版本以来未对资源进行修改时使用 304。
在这种情况下,不需要重新传输资源,因为客户端仍然具有先前下载的副本。
使用它可以在服务器和客户端上节省带宽和重新处理,因为与服务器重新处理的整个页面相比,必须仅发送和接收标头数据,然后使用服务器和客户端的更多带宽再次发送。
307(临时重定向)
307 响应表明 REST API 不会处理客户端的请求。相反,客户端应该将请求重新提交到响应消息的 Location 头指定的 URI。但是,将来的请求仍应使用原始 URI。
REST API 可以使用此状态代码为客户端请求的资源分配临时 URI。例如,307 响应可用于将客户端请求转移到另一个主机。
临时 URI 应该由响应中的 Location 字段给出。除非请求方法是 HEAD,否则响应的实体应该包含一个带有指向新 URI 的超链接的短超文本注释。如果收到 307 状态代码以响应除GET之外的请求HEAD,则用户代理不得自动重定向请求,除非用户可以确认,因为这可能会改变发出请求的条件。
400(不良请求)
400 是通用客户端错误状态,在没有其他 4xx 错误代码适用时使用。错误可能类似于格式错误的请求语法,无效的请求消息参数或欺骗性请求路由等。
客户端不应该在没有修改的情况下重复请求。
401(未经授权)
401 错误响应表示客户端尝试在受保护资源上运行而未提供适当的授权。它可能提供了错误的凭据或根本没有。响应必须包含 WWW-Authenticate 头字段,其中包含适用于所请求资源的质询。
客户端可以使用合适的 Authorization 头字段重复请求。如果请求已包含授权凭据,则 401 响应表示已拒绝授权这些凭据。如果 401 响应包含与先前响应相同的挑战,并且用户代理已经尝试过至少一次认证,则应该向用户呈现响应中给出的实体,因为该实体可能包括相关的诊断信息。
403(禁止)
403 错误响应表明客户端的请求是正确形成的,但 REST API 拒绝遵守它,即用户没有资源的必要权限。403 响应不是客户端凭证不足的情况; 这将是 401(“未经授权”)。
身份验证无济于事,请求不应重复。与 401 Unauthorized 响应不同,身份验证不会产生任何影响。
404(未找到)
404 错误状态代码表示 REST API 无法将客户端的 URI 映射到资源,但可能在将来可用。客户的后续请求是允许的。
没有说明该病症是暂时的还是永久性的。如果服务器通过一些内部可配置的机制知道旧资源永久不可用且没有转发地址,则应该使用 410(Gone)状态代码。当服务器不希望确切地说明请求被拒绝的原因,或者没有其他响应适用时,通常会使用此状态代码。
405(不允许的方法)
API 响应 405 错误以指示客户端尝试使用资源不允许的 HTTP 方法。例如,只读资源只能支持 GET 和 HEAD,而控制器资源可能只允许 GET 和 POST,但不支持 PUT 或 DELETE。
405 响应必须包含 Allow 标头,该标头列出资源支持的 HTTP 方法。例如:
允许:GET,POST
406(不可接受)
406 错误响应表示 API 无法生成任何客户端的首选媒体类型,如 Accept 请求标头所示。例如,application/xml如果 API 仅愿意将数据格式化,则客户端对格式化的数据的请求将接收 406 响应application/json。
如果响应可能是不可接受的,则用户代理应该暂时停止接收更多数据并查询用户以决定进一步的操作。
412(前提条件失败)
412 错误响应表明客户端在其请求标头中指定了一个或多个前提条件,有效地告诉 REST API 仅在满足某些条件时才执行其请求。412 响应表示不满足这些条件,因此 API 不发送请求,而是发送此状态代码。
415(不支持的媒体类型)
415 错误响应表明 API 无法处理客户端提供的媒体类型,如 Content-Type 请求标头所示。例如,application/xml如果 API 仅愿意处理格式化为的数据,则包括格式化的数据的客户机请求将接收 415 响应application/json。
例如,客户端将图像上载为 image / svg + xml,但服务器要求图像使用不同的格式。
500(内部服务器错误)
500 是通用 REST API 错误响应。大多数 Web 框架在执行一些引发异常的请求处理程序代码时会自动响应此响应状态代码。
500 错误绝不是客户端的错误,因此客户端重试触发此响应的完全相同的请求是合理的,并希望获得不同的响应。
API 响应是一般错误消息,在遇到意外情况且没有更合适的消息时给出。
501(未实施)
服务器要么无法识别请求方法,要么无法满足请求。通常,这意味着将来的可用性(例如,Web 服务 API 的新功能)。
3. 请求的类型
以下是与相关描述匹配的属性推荐名称:
| 名称 | 描述 |
|---|---|
| string | 字符串,用于传输文本数据,如用户名称、电子邮件地址、消息内容等。 |
| integer | 整数,用于传输整数值,如用户 ID、订单编号、状态码等。 |
| boolean | 布尔值,用于传输 true/false 值,如表示开关状态、是否启用、是否有效等。 |
| number | 数字,用于传输数值数据,可以是整数或浮点数。 |
| array | 数组,用于传输一组数据,如用户列表、商品列表、订单详情等。 |
4. 返回响应的类型
字段名的类型应与请求期望的类型保持一致。当字段名包含子参数时,这些子参数应被组织在嵌套的 JSON 对象中。以下是一个示例,展示了如何以结构化的方式返回包含子参数的响应:
{
"code": 200,
"message": "查询成功",
"enable": true,
"data": {
"id": 1,
"createTime": 1689571200,
"nick": "张三"
},
"array": [
{
"time": 1689571200,
"money": 21.2,
"message": "消费 0.5 积分"
},
{
"time": 1689571100,
"money": 21.7,
"message": "充值 21.8 积分"
}
]
}| 字段名 | 类型 | 说明 |
|---|---|---|
| code | integer | - |
| message | string | - |
| enblae | boolean | - |
| data.id | integer | - |
| data.createTime | integer | - |
| data.nick | string | - |
| array | array | - |
| array[].time | integer | - |
| array[].age | number | - |
| array[].message | string | - |