欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RestFul设计规范

程序员文章站 2024-03-25 16:41:22
...

1、说明

在整个文档中,会有一些对于标准和实践的推荐和建议。一些实践是非常重要的,必须严格执行,另一些指导准则并不一定处处适用,但是会在特定的场景下带来益处。为了清楚陈述规范和实践的意图,我们会使用如下术语。

2、通用命名约定

命名指南 中的”Restful接口”章节,不一致时以本文档为准。

3、基本设计规范

3.1 关注点分离

设计的时候尽量保持简单,一定要分离请求和响应时关注的不同部分,如:URL、Method、HEADER、body、HTTP Status Codes

3.2 使用HTTPS★

  1. 外部服务一定要使用TLS(就是HTTPS)来访问API,没有必要指出什么时候需要用,什么时候不需要用,只管任何时候都用它;
  2. 内部服务应该使用TLS,当前阶段不作为强制规范;
  3. 对所有非TLS的请求返回403 Forbidden,不要用重定向,这会允许一些不良的客户端行为,而又没有任何好处。依赖重定向的客户端会使流量翻倍,而让TLS毫无意义 — 敏感数据已经在第一次请求时发送出来了。

3.3 版本化API ★

REST版本化和多版本间过渡,是RESTful架构设计和运行时的挑战。因此,最好在一开始就考虑版本。

  1. 一定要在PATH上定义接口版本,如:
    1. https://xxx.xxx.com/upp/cpg/v1
    2. https://xxx.xxx.com/upp/cpg/v2
  2. 如果需要A/B Test,一定要在Request Header上定义,详见Requests设计规
  3. 一定不要提供默认版本,而由客户端显式指定它使用哪一个特定的版本。

3.4 RequestId追溯★

每个API请求一定要包含一个唯一的UUID

UUID存放在HEAD的X-OHM-Request-Id中,用来追溯。 由客户端,服务器和任何后端服务上记录这些值。 当出现问题时,根据这个值可以更容易地找出问题并更迅速地提供解决方案。它提供了一种机制来跟踪,诊断和调试REST请求。

3.5权限分离★

一定要通过url****和端口区分公共、私有、管理api,如:

  1. 公共(public):https://xxx.xxx.com/upp/v1/ 【可选端口:80,8000-8999】
  2. 私有(private):https://internal.xxx.xxx.com:9000/v1/ 【可选端口:9000-9899】
  3. 管理(admin):https://admin.xxx.xxx.com:9900/v1/【可选端口:9900-9999】

3.6 Etags缓存

可以在所有的请求中带上 ETag 头 ,用于识别返回资源的特定版本。用户可以在随后的请求中通过提供If-None-Match头的值来检查内容是否需要更新。

3.7 Ranges分页

可以对所有可能产生大量数据的响应,可以使用Content-Range头来标记分页请求。

3.8过滤、选择、排序

**过滤 Filtering **:

使用唯一的查询参数进行过滤:

curl +X GET https://xxx.xxx.com/v1/cars?color=red 返回红色的cars
curl +X GET https://xxx.xxx.com/v1/cars?seatsTo=2 返回小于两座位的cars集合

选择 Field selection

移动端能够显示其中一些字段,它们其实不需要一个资源的所有字段,给API消费者一个选择字段的能力,这会降低网络流量,提高API可用性。

curl +X GET https://xxx.xxx.com/v1/cars?fields=manufacturer,model,id,color

排序 Sorting :

允许针对多个字段排序

curl +X GET https://xxx.xxx.com/v1/cars?sort=-manufactorer,+model

这是返回根据生产者降序和模型升序排列的car集合

4 请求Requests设计规范

4.1 资源名 ★

  1. 一定使用名词而不是动词
    1. curl +X GET https://xxx.xxx.com/v1/users/{userId}
    2. curl +X GET https://xxx.xxx.com/v1/getUserByID
  2. 一定使用复数名词
    1. /users ý/user
    2. /users/{userId}/apps ý/user/{userId}/app
  3. 使用资源名称的复数版本除非有关资源是在系统内的单(例如,系统的整体状态可能是/status)。这使得它在你提到的特定资源的方式是一致的。

4.2 请求头★

Host: xxx.xxx.xxx.com

Date: Mon, 22 Aug 2016 11:21:04 GMT

User-Agent: Apache-HttpClient/4.1.2 (java 1.6)

**Content-Type: application/x-www-form-urlencoded; charset=UTF-8 **

//请求体类型,请根据实际请求体内容设置

Accept: application/json

//请求响应体类型,部分API可以根据指定的响应类型来返回对应数据格式,建议手动指定此请求头,如果不设置,部分HTTP客户端会设置默认值/,导致签名错误

X-OHM-App-Version: 1.0.0.2a

//APP版本号,用于请求路由、A/B Test等场景

X-OHM-Stage: RELEASE

//请求API的Stage,如TEST、RELEASE,API提供者可以选择发布到哪个Stage,只有发布到指定Stage后API才可以调用,否则会提示API找不到/Invalid Url/签名失败等错误

X-OHM-ClientKey: 60022326

//请求的AppKey,只有获得API授权后才可以调用

X-OHM-Time: 2016-04-06T12:00:00Z

//请求时间戳

**X-OHM-RequestId(必须): 7AD052CB-EE8B-4DFD-BBAF-EFB340E0A5AF **

//请求唯一标识,UUID,建议15分钟内Request-Id不能重复,与时间戳结合使用起到防重放作用

X-OHM-Signature: FJleSrCYPGCU7dMlLTG+UD3Bc5Elh3TV3CWHtSKh1Ys=

//请求签名,用于验签,防止伪造请求,根据接口的安全等级自定义规则,一般httpmethod、header、body、url的重要信息都要包含

X-OHM-UserId:

** X-OHM-UserToken:**

//用户Id和Token

X-OHM-Request-Mode:Debug

//是否开启Debug模式,不设置默认关闭,一般API调试阶段可以打开此设置,打开会接口会返回更相信的deug信息;生产上不允许打开。

X-{产品代码}-XXX

//自定义请求头,如X-UPP-XXX

4.3 操作

一般CRUD操作不需要定义在url中,但如果需要一些特殊的操作可以用actions作为path

示例:/apps/{appId}/actions/start

4.4 正确使用http method ★

仅使用以下四个方法:POST/GET/PUT/DELETE

4.5 少用路径嵌套★

数据模型可能有父子嵌套关系,路径可能深度嵌套

示例:https://xxx.xxx.com/v1/users/{userId}/apps/{appId}/docker/{dockerId}

宁愿在根路径上限制资源嵌套,使用嵌套来表示作用域的集合

例如:一个docker属于一个应用,一个应用属于一个用户

示例:

                     [https://xxx.xxx.com/v1/users/{userId](https://xxx.xxx.com/v1/users/%7BuserId)}

                     [https://xxx.xxx.com/v1/users/{userId}/apps](https://xxx.xxx.com/v1/users/%7BuserId%7D/apps)

                     [https://xxx.xxx.com/v1/apps/{appId](https://xxx.xxx.com/v1/apps/%7BappId)}

                     [https://xxx.xxx.com/v1/apps/{appId}/dockers](https://xxx.xxx.com/v1/apps/%7BappId%7D/dockers)

                     [https://xxx.xxx.com/v1/dockers/{dockerId](https://xxx.xxx.com/v1/dockers/%7BdockerId)}

5 响应Responses设计规范

5.1 返回适当的状态码 ★

rfc7231#section-6中的定义:

  • 1xx (Informational): The request was received, continuing process
  • 2xx (Successful): The request was successfully received, understood, and accepted
  • 3xx (Redirection): Further action needs to be taken in order to complete the request
  • 4xx (Client Error): The request contains bad syntax or cannot be fulfilled
  • 5xx (Server Error): The server failed to fulfill an apparently valid request

成功的响应一定要从以下返回码中进行选择:

  • 200 OK: 请求GET调用成功,对于DELETE方法同步调用完成,或为PUT方法调用,同步更新现有资源
  • 201: 请求POST调用成功,同步完成,或为PUT调用同步创建了一个新的资源
  • 202: 接受POST、PUT、DELETE请求,将异步处理请求结果

错误的响应一定要从以下返回码中进行选择,特别注意400错误,普通业务异常一定要返回400

  • 400 Bad Request:请求失败,普通业务异常 & 服务器不理解请求语法
  • 401 Unauthorized: 请求失败,因为用户没有通过验证
  • **403 ** Forbidden: 请求失败,因为用户没有权限访问特定资源
  • 404 Not Found:请求失败,未找到该资源
  • 408 Request Timeout:请求超时
  • 429 Too Many Requests:超频调用,请稍后再试
  • 500 Internal Server Error:服务器内部错误,检查网站状态或报告问题

5.2 UTC时间并用ISO8601格式化 ★

接受和返回时一定只用UTC时间,并用ISO8601格式化,如:

"finishedAt": "2016-04-06T12:00:00Z"

5.3 生成结构化的错误信息 ★

在报错时生成一致结构的响应请求,包括:

  • code:一个机器可读的错误,
  • message:一个人类可读的错误message,
  • extraCode: 附加错误码,一般用于返回外部服务原始错误码, (可选)
  • extraMessage: 附加错误消息,一般用于返回外部服务原始错误消息,(可选)
  • tracestack:一个程序员可读的错误tracestack,(可选)
  • url:一个url为客户端提供进一步错误信息和解决方案(可选)

示例:

| |

[](https://docs.xxx.xxx.com/XXX)

|

6 文档和其他(参考)

6.1 提供机器可读的json schema

提供机器可读的JSON schema来描述你的API,可以用prmd来管理JSON schema,用prmd verify来确保它通过验证

6.2 提供人类可读的文档

提供人类可读的文档帮助客户端开发者们理解你的API。

如果你使用了prmd来创建schema,那么你可以简单的通过prmd doc命令来生成Markdown的endpoint级别的文档。

除了endpoint级别的描述,还要提供概要级别的信息,

如:

  • 授权,包括获得和使用授权Token。
  • API的稳定性和版本,包括如何选择现有的API版本。
  • 通用请求和响应头。
  • 错误的序列化格式。
  • 各种语言的客户端如何使用API的例子。

6.3 提供可执行的示例

提供可执行的例子,这样用户可以直接在终端输入并看到可以用的API请求。最好的情况是,这些例子可以直接复制粘贴,以最小化用户试用API的成本,

如:

$ export TOKEN=... # acquire from dashboard

$ curl -is https://[email protected]/v1/users

如果你使用prmd来生成Markdown文档,免费获得了可执行的示例。

6.4 提供mockapi

[图片上传失败...(image-b07de4-1526024018097)]

6.5 描述稳定性

描述你API的稳定性,以及哪些endpoint依赖于其成熟度,比如使用prototype,development或者production的标识。

可参考 Heroku API compatibility policy 了解哪些接口是稳定的,哪些可能有变动。

一旦你的API宣布为 production-ready 和 稳定版,不要在该API版本上做任何不向前兼容的修改。如果你需要做不向前兼容的修改,创建一个新的版本号。

[图片上传失败...(image-c70619-1526024018097)]

上一篇: Restful

下一篇: restful设计