HTTP APIs 设计/规范指南
根据REST APIs的成熟度模型 ,此规范关注的是Level 2的APIs。 
1 设计指南
HTTP APIs主要由四部分组成:HTTP,URL,资源,资源的表述(JSON)。资源的表述格式通常都采用JSON,故而后面就使用JSON代指资源的表述。根据这些组成部分,按照以下3个步骤设计APIs:
- 基于
资源设计APIs。 - 基于
URL标识资源。 - 基于
JSON和HTTP操作URL标识的资源。
1.1 基于资源设计API
设计HTTP APIs的首要任务是识别出业务领域中存在的资源。资源是对服务端提供的服务进行分解、组合后的一个被命名的抽象概念。
有一个很重要的点需要明确一下:资源≠数据表,它们两个之间并没有直接的映射关系。如果直接把数据存储结构映射为资源,则只会让资源无法有效的表达业务需要,也会造成资源本身和底层存储的紧耦合。
资源的设计是以名词为中心的。比如今天的天气是一个资源;而获取今天的天气则不是,它代表的是对今天的天气资源的一个读取操作。基于此我们可以抽象出来一个天气的资源。
1.2 基于URL标识资源
识别出资源后,则需要为其分配一个URL进行标识。
- 一个
资源可以有多个URL。 - 一个
URL只能标识一个资源。
总结来说就是
资源:URL的关系就是1:N的关系。
比如上面提到的天气和今天的天气这两个资源,可以用如下的URL进行标识。
| 资源 | URL |
|---|---|
| 天气 | /weathers |
| 今天的天气 | /weathers/today |
| 今天的天气 | /weathers/2018-04-01,今天是2018-04-01 |
资源体现在URL中的Path部分;如果资源代表的是一个集合,则以复数的形式出现。
资源存在子资源的情况下,可以把子资源提升为顶层的资源。比如有一个订单资源/orders/{order_id},订单中包含2件物品。
# 不推荐 单个子资源
/orders/{order_id}/items/{item_id}
# 推荐 单个子资源
/order-items/{order_item_id}
# 推荐 子资源集合
/orders/{order_id}/items
1.3 基于JSON和HTTP操作URL标识的资源
在标识出资源以后,就可以使用HTTP通过JSON来操作资源了。
- 使用
HTTP Method来映射对资源的操作请求(CRUD或者其他)。 - 使用
HTTP Header携带请求/响应所需的元数据信息。 - 使用
HTTP Stauts Code代表HTTP协议层面的响应状态。 - 使用
JSON作为数据交换格式。
2 规范指南
2.1 通用部分
2.2 API版本化
在Level 2的HTTP APIs中,虽然我们推荐也努力使得我们的APIs不做不兼容的改动,但是依然无法彻底的避免不兼容的升级。这就使得我们不得不进行对APIs进行版本管理。通常有以下3种方案:
- URL
GET http://api.linianhui.com/v1/resources HTTP/1.1
- Request Header
GET http://api.linianhui.com/resources HTTP/1.1
Api-Version: v1 - Request Header (Accept Header)
GET http://api.linianhui.com/resources HTTP/1.1
Accept: application/vnd.v1+json
在Level 2中优先推荐使用方案1。理由是其更直观,便于实现,便于日志追踪。
2.3 错误处理
虽然HTTP Stauts Code有4xx和5xx的状态码来表示哪里出错了,但是其代表的只是HTTP协议层面的错误描述,它无法提供和业务相关的更具体错误描述。基于此种情况,我们需要设计一套描述业务层面错误的数据结构:
[
{
"error": "user_name",
"message": "用户名不能为空。"
},
{
"error": "age",
"message": "用户年龄不能小于0。"
}
]
- 这个数据结构仅在状态码为
4xx和5xx出现的时候才会使用;2xx的时候则不包含此数据结构。 error字段可以是一些出错的字段名、某一错误类别(比如no_permission)等等。[
{
"error": "no_permission",
"message": "没有user.delete的权限"
}
]
2.4 Request 公共查询参数
| 参数用途 | 参数名 | 取值范围 |
|---|---|---|
| 分页 | pagepage_size |
>=1 |
| 排序 | sort |
{field_name}|{asc|desc},{field_name}|{asc|desc} |
| 区间 | {field_name}_before{field_name}_after |
无要求 |
| 时间 | {field_name}_at |
无要求 |
示例:
GET /users?page=2&page_size=10&sort=name,age|desc&created_at_after=2018-01-01&created_at_before=2018-06-01 HTTP/1.1
上面的查询代表的含义:按照name升序和age倒序的排序方式;获取created_at时间位于2018-01-01和2018-06-01区间内;按照每页10条数据,获取第2页的数据。
2.5 Response 分页数据结构
在分页请求的时候,API会返回分页后的数据和分页的信息。
{
"page": 2,
"page_size": 10,
"total_count": 100,
"items":[
{...},
{...},
]
}
3 示例
... 待补充
参考资料
PayPal的API设计指南:https://github.com/paypal/api-standards
REST架构风格的出处:架构风格与基于网络的软件架构设计(by Fielding, R.)论文。
- 英文版: https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
- 中文版: http://www.infoq.com/cn/minibooks/web-based-apps-archit-design
- 本人的解读REST系列博客:http://www.cnblogs.com/linianhui/category/774322.html
HTTP APIs 四大组成部分(HTTP,URI,MIME,JSON)
- HTTP/1.1 ( RFC7230-7235 ) :https://tools.ietf.org/html/rfc7230
- URI ( RFC 3986 ) :https://tools.ietf.org/html/rfc3986
- MIME ( RFC 2387 ):https://tools.ietf.org/html/rfc2387
- JSON : http://json.org/
Hypermedia
- JSON Schema: http://json-schema.org/
URL模板
- URI Template ( RFC6570 ) :https://tools.ietf.org/html/rfc6570
时间日期格式化
- Date and Time Formats - ISO 8601:https://www.w3.org/TR/NOTE-datetime
- Date and Time on the Internet: Timestamps ( RFC 3339 ) :https://tools.ietf.org/html/rfc3339#section-5.6
国际化
- https://www.iso.org/iso-3166-country-codes.html
- https://www.iso.org/iso-4217-currency-codes.html
- https://www.iso.org/iso-639-language-codes.html
REST APIs 成熟度模型:https://martinfowler.com/articles/richardsonMaturityModel.html
HTTP APIs 设计/规范指南的更多相关文章
- ASIC设计-终极指南
ASIC设计-终极指南 ASIC Design – The Ultimate Guide ASIC设计-终极指南 ASICs代表特定于应用的集成电路,指的是针对特定应用而设计的半导体解决方案,与其他解 ...
- JavaScript编码规范指南
前言 本文摘自Google JavaScript编码规范指南,截取了其中比较容易理解与遵循的点作为团队的JavaScript编码规范. JavaScript 语言规范 变量 声明变量必须加上 var ...
- atitit.api设计 方法 指南 手册 v2 q929.docx
atitit.api设计 方法 指南 手册 v2 q929.docx atitit.api设计原则与方法 1. 归一化(锤子钉子理论)1 1.1. 链式方法2 1.2. 规则5:建立返回值类型2 1. ...
- MarkDown编写规范指南
Markdown 编写规范指南 简介: Markdown的目标是实现「易读易写」,成为一种适用于网络的「书写语言」. 一份使用Markdown格式撰写的文件可以直接以纯文本发布,它的最大灵感来源其实是 ...
- OC 开发规范指南 - 个人见解写的很好
纽约时报 移动团队 Objective-C 规范指南 这份规范指南概括了纽约时报 iOS 团队的代码约定. 介绍 关于这个编程语言的所有规范,如果这里没有写到,那就在苹果的文档里: • Objecti ...
- 最全面的 Android 编码规范指南
最全面的 Android 编码规范指南 本文word文档下载地址:http://pan.baidu.com/s/1bXT75O 1. 前言 这份文档参考了 Google Java 编程风格规范和 Go ...
- #Google HTML&CSS规范指南
Google HTML&CSS规范指南 翻译自原文 目录 Google HTML&CSS规范指南 1. 背景 2. 通用 2.1 通用样式规则 2.1.1 协议 2.2 通用格式规则 ...
- 字节跳动前技术总监开源分享《Android架构设计权威指南》,YYDS!
架构就像是一场进化史,根据不同时期的需求,演变出不同的架构,车轮滚滚,到今天,移动端框架百花齐放,让人目不暇接.但是其中的本质是磨灭不了的,换言之根本没有磨灭而是隐藏到了人们所看不到的地方,但是依旧发 ...
- Git常用命令和Git团队使用规范指南
转自:https://wsgzao.github.io/post/git/ 前言 在2005年的某一天,Linux之父Linus Torvalds 发布了他的又一个里程碑作品——Git.它的出现改变了 ...
随机推荐
- 如何查看服务器对外的IP
开发的时候经常会被IP受限,这是由于数据源方限制了IP,所以需要报备一下IP白名单,怎么查看自己的网络对外的IP呢? 用下面的方式最为准确: Windows上操作: 直接再浏览器访问 http://h ...
- SAP Hybris Discount group,折扣组,折扣记录,用户组几组概念的关联
在backoffice的Price Settings->Discount->Customer Discount Groups菜单下面,创建一个新的Customer Discount Gro ...
- js 数组去重求和 (转载)
方法一:js数组id去重,value值相加问题 来源:https://www.jianshu.com/p/8f79e31b46ed // js let arr = [ { id: 1, value: ...
- index.jsp乱码问题的解决
我们在做java项目的时候,都会有个首页,一般就是index.jsp,然后在index.jsp中引入相关的文件,一般也是引入打包过后的相关资源文件. 当index.jsp上面的中文出现乱码的时候,就需 ...
- MySQL Case--优化OR语句踩坑记录
问题描述 研发同事反馈某应用执行较慢,对应SQL为: UPDATE bs_serial_trac , LOCK_VALUE = '', UPDATE_USER = 'transSys' ' AND ( ...
- python模块之json pickle
1.json模块 功能:将其他形式的数据类型转化为json字符串类型,将json字符串转化为其他对应的数据类型 方法:json.dumps() 作用:将所有单引号变成双引号:将所有数据类型变成字符串 ...
- k8s之pod与Pod控制器
k8s中最为重要的基础资源,pod,pod controller,service pod controller类型有多种需要向控制器赋值之后使用: kubectl命令使用 kubectk get no ...
- jquery 内容筛选选择器
基本筛选选择器针对的都是元素DOM节点,如果我们要通过内容来过滤,jQuery也提供了一组内容筛选选择器,当然其规则也会体现在它所包含的子元素或者文本内容上 注意事项: :contains与:has都 ...
- drf框架总结复习(1)
Serializers 序列化组件 为什么要用序列化组件 当我们做前后端分离的项目~~我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成j ...
- 08 c++中运算符重载(未完成)
参考:轻松搞定c++语言 定义:赋予已有运算符多重含义,实现一名多用(比较函数重载) 运算符重载的本质是函数重载 重载函数的格式: 函数类型 operator 运算符名称(形参表列) { 重载实体 ...