• 概述

WEB API的应用场景设计和实现非常丰富,例如:将已有系统的功能或数据开放给合作伙伴或生态圈;对外发布可嵌入到其他网页的微件;构建前后端分离的WEB应用;开发跨不同终端的移动应用;集成公司内部不同系统等等。在上述场景里,你可能是WEB API的使用者,也可能是设计者,但你知道如何评判WEB API的优劣吗?

  • 评判标准

我们可以从三个维度来评判一个WEB API的优劣:

  • 易于使用:WEB API的用户是程序还是人?我觉得首先是人,然后是程序。为什么这么说呢?是否采用某个WEB API的决定是人做出的,一个好的WEB API必须符合人的审美,例如:简短易记、通俗易懂、便于输入等。从程序角度看,WEB API应该遵循行业规范,在调用时不需要做特殊化处理,有利于复用已有的代码或工具。
  • 便于更改:一个WEB API发布上线之后,免不了要根据真实用户的反馈或者业务发展的需要做更新修改,这些更新修改必须尽量不影响用户。要么提供多版本支持,要么给用户提供切实可行的更新策略等等。
  • 健壮稳定:对外公开的WEB API存在被攻击的风险,以及无法准确预估的访问量等,一个好的WEB API必须要有防注入、防篡改、防重放等安全机制,还要在访问量急剧上涨时避免服务被击穿。

做到了上述三个方面,我们才有底气将一个WEB API对外开放,接受公众的检验。好的WEB API不仅方便使用,还助于提升个人或企业的技术影响力,从而形成正向循环,带来越来越多的业务价值。为了设计出优美的WEB API,我们需要了解与之相关的设计规范和事实标准,并且在设计开发过程中尽量遵循它们。

  • 设计规范

URI

  • 便于输入的URI,简短不冗余。每个WEB API都是一个服务,那下面反例当中的“service”就是冗余的,而且“api”也重复出现了两次,这种冗余都不利于记忆和输入:

反例:http://api.example.com/service/api/users

正例:http://api.example.com/users

  • 容易读懂的URI,不要随意采用缩写,缩写必须要符合国际标准规范,不要凭空发明创造,例如:国家代码定义(ISO3166)。反例中出现了两处缩写“sv”、“u”,在没有附加说明的情况下,用户压根不知道含义:

反例:http://api.example.com/sv/u

  • 没有大小写混用的URI。HTTP协议(RFC7230)规定:除了模式(schema)和主机名以外,URI的其他信息都要区分字母的大小写。下述两个反例大小写混用,不方便记忆。

反例:http://api.example.com/Users/12345

反例:http://example.com/API/getUserName

  • 易于修改的URI,命名存在可预见的规律。下述正例我们可以很容易猜测改变最后的ID就可以访问其他商品的信息。

正例:http://api.example.com/v1/items/123456

  • 不会暴露服务端架构的URI,URI只需要体现功能、数据结构和含义,无需暴露服务端如何运作的信息。这些信息对用户来说没有意义,还存在潜在的风险,恶意用户或者黑客会利用这些信息来寻找漏洞,发起对服务的攻击。

反例:http://api.example.com/cgi-bin/get_user.php?user=100

  • 规则统一的URI,确保采用统一的规则和风格,方便用户记忆和使用。下述反例中第一个URI采用了查询参数,第二个URI采用了路径参数,这两者没有保持一致,容易造成混乱。

反例:获取好友信息,http://api.example.com/friends?id=100

反例:发送消息,http://api.example.com/friend/100/messages

正例:获取好友信息,http://api.example.com/friends/100

正例:发送消息,http://api.example.com/friends/100/messages

  • URI最好由名词组成。URI的全称是统一资源定位符(Uniform Resource Identifier),用于标识资源在互联网上的位置,类似于邮寄地址,而地址都是由名词组成的。在名词使用上也有一些需要注意的事项:其一,使用名词复数形式;其二,尽量采用多数API中使用的表示相同含义的单词;其三,通过尽可能少的单词来表示;其四,尽可能不用奇怪的缩略语等。
  • 不使用空格及需要编码的字符,例如在URI中使用中文等。
  • 使用连接符(-)来连接多个单词,推荐脊柱法:首先,URI里的主机名(域名)允许使用连字符而禁止使用下划线,且不区分大小写。其次,点字符具有特殊含义,为了与主机名的规则保持一致。

脊柱法:http://api.example.com/v1/users/12345/profile-image

蛇形法:http://api.example.com/v1/users/12345/profile_image

驼峰法:http://api.example.com/v1/users/12345/profileImage

查询参数

  • 许多场景下需要通过API分批次获取数据,我们会经常纠结采用什么样的查询参数,业界有两种常用的参数设计(per-page与page、limit与offset),用于标识每次获取的数据量和起始位置。在分批次获取数据的过程中,数据集合中的记录可能发生增删改变,我们需要注意采用相对位置或绝对位置所带来的不同效果。

风格1:http://api.example.com/friends?per-page=50&page=3

风格2:http://api.example.com/friends?limit=50&offset=100

  • 在设计过滤的参数时,业界也有一些事实标准可供参考。如果我们期望查询结果的特定属性取值跟过滤参数的取值完全相同,那过滤参数的名称通常为属性名;如果我们期望查询结果任意属性部分包含过滤参数的取值,那过滤参数的名称通常为“q”。

完全符合:http://api.example.com/v1/users?name=ken

全文搜索:http://api.example.com/v1/users?q=ken

  • URI是否可以包含动词“search”?通常以搜索为主的在线服务API可以包含,除此之外建议采用名词复数形式。常用英文单词“search”和“find”都有查找的含义,但两者还是有一些细微的差别,其中“search”用于模糊搜索,而“find”用于精准查询。

模糊搜索:http://yboss.yahooapis.com/ysearch/web?q=ipod

  • 某个属性究竟是作为URI路径的构成元素还是作为查询参数呢?我们可以按照以下规则来判断:如果该属性信息可以唯一定位资源,那么它就适合作为路径构成元素,否则就作为查询参数;如果该属性可以省略,那么它就是适合作为查询参数。

路径元素:http://api.example.com/v1/users/{id}

查询参数:http://api.example.com/v1/users?name=ken

HTTP方法

按照HTTP协议设计的本意,URI用于标识被操作的目标对象(资源),而HTTP方法则是表示操作方法。基于HTTP协议的简单对象访问协议SOAP逐渐被RESTful的原生HTTP协议取代,我们也没有必要画蛇添足,最好就是吃透HTTP协议,充分利用它的特性。

1

2

GET /v1/users/123 HTTP/1.1

Host: api.example.com

  • GET,获取资源
  • POST,新增资源
  • PUT,更新已有资源
  • DELETE,删除资源
  • PATCH,更新部分资源
  • HEAD,获取资源的元信息

如果遇到上述HTTP方法无法覆盖的场景,那通常是资源的设计粒度太大了,我们可以把粗粒度的资源分解成多个细粒度的资源。在使用HTTP协议设计WEB API的专业能力上,业界将其划分为四个层级,LEVEL3相对较理想化,缺乏实施的基础,LEVEL2是切实可行的:

  • LEVEL 0:使用HTTP
  • LEVEL 1:引入资源的概念
  • LEVEL 2:引入HTTP动词(GET/POST/PUT/DELETE等)
  • LEVEL 3:引入HATEOAS概念

响应数据

常用的数据格式有:HTML、XML、JSON、YAML等,如果我们的服务在响应时支持不同类型的数据格式,那应用在调用服务时如何获得期望格式的响应数据呢?通常我们可以考虑采用下述几种指定数据格式的方法:

  • 使用查询参数的方法:

示例:https://api.example.com/v1/users?format=xml

  • 使用扩展名的方法:

1

示例:https://api.example.com/v1/users.json

  • 使用在请求首部指定媒体类型的方法,优先推荐此种方法:

GET /v1/users

Host: api.example.com

Accept: application/json

响应数据应该包含哪些信息呢?是否越多越好?亦或越少越好,仅仅包含ID?建议是按需返回,根据业务功能所需返回相应的数据。如果一个WEB API需要提供给不同业务场景使用,不同业务场景对数据属性信息的要求不同,或多或少,这种情况我们可以让用户来选择响应的内容,选择方法就是通过查询参数指定:

示例:http://api.example.com/v1/users/123?fields=name,age

响应数据的结构应该尽量扁平化,不要嵌套太深,减少没有具体含义的信息载荷,这样既可以压缩报文尺寸,又可以节省带宽的。当然,如果层级结构更具优势,也可以采用。

出错信息

建议通过HTTP协议首部的状态码来表示出错信息,而不是再封装一层,遵守协议规范的好处是可以减少沟通的成本,也可以利用许多成熟的软硬件产品来处理异常出错信息。HTTP协议定了了五种类型的状态码:

  • 1XX:消息
  • 2XX:成功
  • 3XX:重定向
  • 4XX:客户端原因引起的错误
  • 5XX:服务器端原因引起的错误

我们需要每种状态码的使用场景,确保正确使用状态码。除此之外,服务还需要向客户端返回详细的出错信息,我们通常可以采用下述两种方法来传递详细的出错信息:

  • 方法1:定义私有的首部,将其填入响应消息的首部。
  • 方法2:将详细的出错信息放入消息体。

版本管理

随着业务的发展,每个发布上线的WEB API都存在更新修改的可能,那就需要引入版本管理的机制。业界有三种常见的标注WEB API版本的方法:

  • 在URI中嵌入版本编号:

示例:http://api.linkedin.com/v1/people

  • 在查询字符串里加入版本信息:

示例:http://api.example.com/users/123?v=2

  • 通过媒体类型来指定版本信息

Accept: application/vnd.github.v3+json

Content-Type: application/vnd.github.v3+json 

同样,版本编号也存在业界规范:语义化版本控制(Semantic Versioning)规范,网站地址:semver.org。版本编号由点号连接的3个数字组成,例如:1.2.3,分别表示主版本编号、次版本编号、补丁版本编号,版本编号的增加遵循下述规则:

  • 在对软件进行不向下兼容的变更时,增加主版本编号;
  • 在对软件进行向下兼容的变更或废除某些特定的功能时,增加次版本编号;
  • 如果软件的API没有发生变更,只是修正了部分bug,则增加补丁版本编号。

按照版本编号增长的规则,WEB API的版本编号只需要标注主版本编号就可以了,因为次版本编号、补丁版本编号的增加都可以做到向下兼容,不会影响用户使用,唯有主版本编号增加才需要用户更新升级。除了标注版本信息之外,我们在对外发布WEB API时还需要设计好版本变更的策略,例如:老版本提供多久的过渡期、同时兼容多少个版本、特定版本的终止日期等等。

API的应用场景设计和实现相关推荐

  1. WEB API系列(一):WEB API的适用场景、第一个实例

    在我前一篇博客<WebAPI前置知识:HTTP与RestfulAPI>中已经给各位简单介绍了HTTP协议与RestFul API的关系,以及一些基本的HTTP协议知识,在这些知识的铺垫下, ...

  2. Taobao平台API的应用场景和实例

    api是什么意思(api通俗解释) API的意思是:简单来说就是函数.比如你写了一个库,里面有很多函数,如果别人要使用你这个库,但是并不知道每个函数内部是怎么实现的.使用的人需要看你的文档或者注释,才 ...

  3. API 快速开发平台设计思考

    作者 | 人月聊IT 来源 | toutiao.com/i6914469326074479108 在我之前谈API网关的时候曾经谈到过快速开发平台,即将API快速开发的一些内容放入到API网关中,实际 ...

  4. 对外API接口的安全性设计及鉴权方式

    对外API接口的安全性设计及鉴权方式 API鉴权方式 API Key + API Secret实现API鉴权 Cookie + Session实现API鉴权 token机制实现API鉴权 API接口的 ...

  5. UE4风格化场景设计入门指南 Stylized Station – The Environment Artist’s Survival Kit

    持续时间13h 1920X1080 .ts 包含项目文件 大小解压后:4.9G 语言:英语+中文字幕(人工校对) 标题:风格化的车站--环境艺术家的生存工具包 信息: 环境艺术很难. 尤其是作为初学者 ...

  6. Sketchup插件Vray户外场景设计渲染教程 Vray Next For Sketchup Exterior

    Sketchup户外场景设计的Vray Next 你会学到什么 渲染白天和夜晚场景 后期制作 Sketchup的Vray Next 中级sketchup用户 大小解压后:3.83G 1280X720 ...

  7. UE4场景设计学习教程

    视频:MPEG4视频(H264) 1920×1080 25fps 1400kbps |音频:AAC 44100Hz立体声128kbps 语言:西班牙语+中英文字幕(根据原英文字幕机译更准确) |时长: ...

  8. 性能测试场景设计之用户模式设置

    性能测试场景设计之参数设计 1.用户模式设置 场景执行前需要根据系统特性对场景进行配置,以便对系统进行负载测试时压力状况更加符合业务特性.相关的参数配置如下: 首先新建场景,如下: 场景新建的时候一般 ...

  9. 视频编辑SDK---我们只提供API,任你自由设计炫酷的功能

    面对相对复杂的视频编辑处理技术,你是否束手无策? 在短视频应用中,有一定技术难度的视频编辑技术中,我们提出了一种全新的解决方法:画板和画笔. 短视频处理,用画板和画笔,就够了! 我们设计了极其简单易懂 ...

最新文章

  1. 13、JsonResponse响应介绍
  2. java开发用amd处理器_HBase1.x实战:协处理器Java开发实例--ObserverCoprocessor
  3. Linux基础之文件管理三兄弟(cp、mv、rm)
  4. P1232-[NOI2013]树的计数【思维】
  5. xflash里的hello world程序
  6. 外部导入方式添加背景图_web前端基础:CSS的三种导入方式说明
  7. linux上设置svn账户权限设置密码,Linux:如何在svn中设置“全局”用户/密码/组文件...
  8. 多变量频率统计——r
  9. kangle 3.4.8 发布,国产开源 Web 服务器
  10. oj交java代码_UvaOJ java输入代码
  11. 项目服务器装系统,项目1服务器系统的安装.ppt
  12. 二进制数的算术运算和逻辑运算
  13. 关于微信卡券网页跳转链接能力的下线
  14. Linux数据库迁移
  15. 基于XTerm模拟发包实现
  16. JS的迭代器和可迭代对象详解
  17. 毕业这么多年,为啥升职加薪这么难?
  18. 计算机桌面任务栏怎样显示输入法,计算机中任务栏的输入法无法切换怎么处理...
  19. 广东某银行基于阿凡搭在信创环境下打造全行科技一体化服务平台
  20. python 圆形检测_python下用OpenCV的圆形检测

热门文章

  1. del关键字在python中的作用
  2. 21世纪前端最牛学习资料
  3. android中的数字签名技术
  4. php imagemagick安装,php ImageMagick windows下安装教程
  5. python定义变量参数_Python变量定义与使用
  6. Cesium terrain
  7. ADOBE FLASH ON 介绍
  8. 注意力机制(Attention)原理详解
  9. 家庭娱乐用计算机,如何将普通PC电脑变成“家庭娱乐共享中心”的详细教程
  10. ArcGIS10.2保姆式安装教程,超详细;附安装包