Web API设计方法论

标签: web api 设计 | 发表时间:2015-02-15 10:43 | 作者:
出处:http://kb.cnblogs.com/

  英文原文: A Web API Design Methodology

   Web 设计、实现和维护 API 不仅仅是一项挑战;对很多公司来说,这是一项势在必行的任务。 本系列 将带领读者走过一段旅程,从为 API 确定业务用例到设计方法论,解决实现难题,并从长远的角度看待在 Web 上维护公共 API 。沿途将会有对有影响力的人物的访谈,甚至还有 API 及相关主题的推荐阅读清单。

   这篇 InfoQ 文章是 Web API 从开始到结束 系列文章中的一篇。你可以在 这里 进行订阅,以便能在有新文章发布时收到通知。

  设计Web API不止是URL、HTTP状态码、头信息和有效负载。设计的过程--基本上是为了你的API“观察和感受” -- 这非常重要,并且值得你付出努力。本文简要概括了一种同时发挥HTTP和Web两者优势的API设计方法论。并且它不仅对HTTP有效。如果有时你还需要通过WebSockets、XMPP、MQTT等实现同样的服务,大部分API设计的结果同样可用。可以让未来支持多种协议更容易实现和维护。

   优秀的设计超越了URL、状态码、头信息和有效负载

  一般来说, Web API设计指南的重点是通用的功能特性,比如URL设计,正确使用状态码、方法、头信息之类的HTTP功能特性,以及持有序列化的对象或对象图的有效负载设计。这些都是重要的实现细节,但不太算得上API设计。并且正是API的设计--服务的基本功能特性的表达和描述方式--为Web API的成功和可用性做出了重要贡献。

  一个优秀的设计过程或方法论定义了一组一致的、可重复的步骤集,可以在将一个服务器端服务组件输出为一个可访问的、有用的Web API时使用。那就是说,一个清晰的方法论可以由开发人员、设计师和软件架构师共享,以便在整个实现周期内帮助大家协同活动。一个成熟的方法论还可以随着时间的发展,随着每个团队不断发现改善和精简过程的方式而得到精炼,却不会对实现细节产生不利的影响。实际上,当 实现细节设计过程两者都有清晰的定义并相互分离时,实现细节的改变(比如采用哪个平台、OS、框架和UI样式)可以独立于设计过程。

   API设计七步法

  接下来我们要对Richardson和Amundsen合著的《 REST风格的Web API》一书中所介绍的设计方法论做简要地概述。因为篇幅所限,我们不能深入探讨这一过程中的每一步骤,但这篇文章可以让你有个大概的认识。另外,读者可以用这篇概述作为指南,根据自己组织的技能和目标开发一个独有的Web API设计过程。

   说明:是的, 7 步看起来有点儿多。实际上清单中有 5 个步骤属于设计,额外还有两个条目是实现和发布。最后这两个设计过程之外的步骤是为了提供一个从头到尾的体验。

  你应该计划好根据需要重新迭代这些步骤。通过步骤2(绘制状态图)意识到在步骤1(列出所有组成部分)有更多工作要做。当你接近于写代码(步骤6)时,可能会发现第5步(创建语义档案)中漏了一些东西。关键是用这个过程暴露尽可能多的细节,并愿意回退一步或者两步,把前面漏掉的补上。迭代是构建更加完整的服务画面以及澄清如何将它暴露给客户端程序的关键。

   步骤1 : 列出所有组成部分

  第一步是列出客户端程序可能要从我们的服务中获取的,或要放到我们的服务中的所有数据片段。我们将这些称为语义描述符。语义是指它们处理数据在应用程序中的含义,描述符是指它们描述了在应用程序自身中发生了什么。注意,这里的视点是客户端,不是服务器端。将API设计成客户端使用的东西很重要。

  比如说,在一个简单的待办事项列表应用中,你可能会找到下面这些语义描述符:

  • id : 系统中每条记录的唯一标识符
  • title : 每个待办事项的标题
  • dateDue : 待办事项应该完成的日期
  • complete : 一个是/否标记,表明待办事项是否已经完成了。

  在一个功能完备的应用程序中,可能还会有很多语义描述符,涉及待办事项的分类(工作、家庭、园艺等),用户信息(用于多用户的实现)等等。不过为了突出过程本身,我们会保持它的简单性。

   步骤2 : 绘制状态图

  下一步是根据建议的API绘制出状态图。图中的每个框都表示一种可能的表示--一个包含在步骤1中确定的一或多个语义描述符的文档。你可以用箭头表示从一个框到下一个的转变--从一个状态到下一个状态。这些转变是由协议请求触发的。

  在每次变化中还不用急着指明用哪个协议方法。只要标明变化是安全的(比如HTTP GET),还是不安全/非幂等的(比如HTTP.POST),或者不安全/幂等的(PUT)。

   说明:幂等动作是指重复执行时不会有无法预料的副作用。比如 HTTP PUT ,因为规范说服务器应该用客户端传来的状态值替换目标资源的已有值,所以说它是幂等的。而 HTTP POST 是非幂等的,因为规范指出提交的值应该是追加到已有资源集合上的,而不是替换。

  在这个案例中,我们这个简单的待办事项服务的客户端应用程序可能需要访问可用条目的清单,能过滤这个清单,能查看单个条目,并且能将条目标记为已完成。这些动作中很多都用状态值在客户端和服务器之间传递数据。比如add-item 动作允许客户端传递状态值title和dueDate。下面是一个说明那些动作的状态图。

  这个状态图中展示的这些动作(也在下面列出来了)也是语义描述符-- 它们描述了这个服务的语义 动作

  • read-list
  • filter-list
  • read-item
  • create-item
  • mark-complete

  在你做这个状态图的过程中,你可能会发现自己漏掉了客户端真正想要或需要的动作或数据项。这是退回到步骤1的机会,添加一些新的描述符,并/或者在步骤2中改进状态图。

  在你重新迭代过这两步之后,你应该对客户端跟服务交互所需的所有数据点和动作有了好的认识和想法。

   步骤 3 : 调和魔法字符串

  下一步是调和服务接口中的所有“魔法字符串”。“魔法字符串” 全是描述符的名称--它们没有内在的含义,只是表示客户端跟你的服务通讯时将要访问的动作或数据元素。调和这些描述符名称的意思是指采用源自下面这些地方的,知名度更高的公共名称:

  这些全是明确定义的、共享的名称库。当你服务接口使用来自这些源头的名称时,开发人员很可能之前见过并知道它们是什么意思。这可以提高API的可用性。

   说明:尽管在服务接口上使用共享名称是个好主意,但在内部实现里可以不用(比如数据库里的数据域名称)。服务自身可以毫不困难地将公共接口名称映射为内部存储名称。

  以待办事项服务为例,除了一个语义描述符- create-item,我能找到所有可接受的已有名称。为此我根据 Web Linking RFC5988中的规则创建了一个具有唯一性的URI。在给接口描述符选择知名的名称时需要折中。它们极少能跟你的内部数据存储元素完美匹配,不过那没关系。

  这里是我的结果:

  经过名称调和,我的状态图变成了下面这样:

   步骤 4 : 选一个媒体类型

  API设计过程的下一步是选一个媒体类型,用来在客户端和服务器端之间传递消息。Web的特点之一是数据是通过统一的接口作为标准化文档传输的。选择同时支持数据描述符(比如"identifier"、"status"等)和动作描述符(比如"search"、"edit"等)的媒体类型很重要。有相当多可用的格式。

  在我写这篇文章时,一些顶尖的超媒体格式是 (排名不分先后):

  • 超文本标记语言 ( HTML)
  • 超文本应用程序语言( HAL)
  • Collection+JSON ( Cj)
  • Siren
  • JSON-API
  • 交换表达式的统一基础 ( UBER)

  让所选择的媒体类型适用于你的目标协议也很重要。大多数开发人员喜欢用 HTTP 协议做服务接口。然而 WebSocketsXMPPMQTTCoAP 也会用--特别是对于高速、短消息、端到端的实现。

  在这个例子中,我会以HTML为消息格式,并采用HTTP协议。HTML有所有数据描述符所需的支持(<UL>用于列表, <LI>用于条目, <SPAN>用于数据元素)。它也有足够的动作描述符支持 (<A>用于安全链接, <FORM method="get">用于安全转变, <FORM method="post">用于非安全转变)。

   注意:在这个状态图中, 编辑 动作是幂等的(比如 HTTP PUT ),并且 HTML 仍然没有对 PUT 的原生支持。在这个例子中,我会添加一个域来将 HTML POST 做成幂等的。

  好了,现在我可以基于那个状态图创建一些样例表示来“试试”这个接口了。对我们的例子而言,只有两个表示要渲染:“待办事项列表”和“待办事项条目”表示:

   1 :用 HTML 表示待办事项列表集合

   图2 :用 HTML 表示待办事项条目

  记住,在你做状态图的表示样例时,可能会发现之前的步骤中有所遗漏(比如漏掉描述符,动作描述符中有幂等之类的变化等)。那也没关系。现在就是解决所有这些问题的时机-- 在你把这个设计变成代码之前。

  等你对表示完全满意之后,在开始写代码之前还有一个步骤--创建语义档案。

   步骤 5 : 创建语义档案

  语义档案是一个文档,其中列出了设计中的所有描述符,包括对开发人员构建客户端和服务器端实现有帮助的所有细节。这个档案是一个实现 指南,不是实现描述。这个差别很重要。

   服务描述符的格式

  服务描述文档格式已经出现了相当长一段时间了,并且当你想给已有的服务实现生产代码或文档时很方便。确实有很多种格式。

  在我写这篇文章时,顶级竞争者有:

   档案的格式

  现在只有几种档案格式。我们推荐下面两种:

  这两个都比较新。JSON-LD规范在2014年早期达成了W3C推荐状态。Hydra仍是一个非官方草案(本文写成时还是),有一个活跃的开发者社区。ALPS仍处于IETF的早期草案阶段。

  因为档案文档的理念是要描述一个问题空间的现实生活方面(不只是那一空间中的单一实现),所以其格式跟典型的描述格式十分不同:

   3 : ALPS 格式的待办事项列表语义档案

  你会注意到,这个文档就像一个基本的词汇表,包含了待办事项服务接口中所有可能的数据值和动作--就是这个理念。同意遵循这个档案的服务可以自行决定它们的协议、消息格式甚至URL。同意接受这个档案的客户端将会构建为可以识别,如果合适的话,启用这个文档中的描述符。

  这种格式也很适合生成人类可读的文档,分析相似的档案,追踪哪个档案用得最广泛,甚至生成状态图。但那是另外一篇文章的课题了。

  现在你有完整的已调和名称的描述符清单,已标记的状态图,以及一个语义档案文档,可以开始准备编码实现样例服务器和客户端了。

   步骤 6 : 写代码

  到了这一步,你应该可以将设计文档(状态图和语义档案)交给服务器和客户端程序的开发人员了,让他们开始做具体的实现。

  HTTP服务器应该实现在第2步中创建的状态图,并且来自客户端的请求应该触发正确的状态转变。服务发送的每个表示都应该用第3步中选好的格式,并且应该包含一个第4步中创建的指向一个档案的链接。响应中应该包含相应的超媒体控件,实现了在状态图中显示、并在档案文档中描述的动作。客户端和服务器端开发人员在这时可以创建相对独立的实现,并用测试验证其是否遵守了状态图和档案。

  有了稳定的可运行代码,还有一步要做:发布。

   步骤 7 : 发布你的API

  Web API应该至少发布一个总能给客户端响应的URL -- 即便是在遥远的将来。我将其称为“看板URL” --每个人都知道的。发布档案文档也是个好主意,服务的新实现可以在响应中链接它。你还可以发布人类可读的文档、教程等,以帮助开发人员理解和使用你的服务。

  做好这个之后,你应该有了一个设计良好的、稳定的、可访问的服务运行起来了,随时可以用。

   总结

  本文讨论了为Web设计API的一组步骤。重点是让数据和动作描述正确,并以机器可读的方式记录它们,以便让人类开发人员即便不直接接触也能轻松为这个设计实现客户端和服务器端。

  这些步骤是:

  1. 列出所有组成部分

    收集客户端跟服务交互所需的所有数据元素。

  2. 绘制状态图

    记录服务提供的所有动作(状态变化)

  3. 调和魔法字符串

    整理你的公开接口以符合(尽可能)知名的名称

  4. 选择媒体类型

    评审消息格式,找到跟目标协议的服务转变最贴近的那个。

  5. 创建语义档案

    编写一个档案文档,定义服务中用的所有描述符。

  6. 写代码

    跟客户端和服务器端开发人员分享档案文档,并开始写代码测试跟档案/状态图的一致性,并在有必要时进行调整。

  7. 发布你的API

    发布你的"看板URL"和档案文档,以便其他人可以用他们创建新的服务以及/或者客户端程序。

  在你的设计过程中,你可能会发现有遗漏的元素,需要重做某些步骤,以及要做一些折中的决定。这在设计过程中出现得越早越好。将来开发人员要求用新的格式和协议实现时,你还有可能用这个API设计。

  最后,这个方法论只是为Web API设计过程创建一种可靠、可重复、一致的设计过程的一种可能方式。在你做这个例子时,可能会发现插入一些额外的步骤,或者缩减一些会更好用,并且-- 当然 -- 消息格式和协议决策在不同案例中可能也会发生变化。

  希望这篇文章能给你一些启发,让你知道如何给自己的组织以及/或者团队创建一个最佳的API设计方法论。

相关 [web api 设计] 推荐:

Web API 设计摘要

- - CSDN博客架构设计推荐文章
最近读了一本微电子书 Brian Mulloy 所著《Web API Design》感觉颇多收获,特对其内容做了个整理摘要以便回顾其观点精华以指导日常工作中的设计思路. 本文主要讲述 Web API 设计,追求一种更务实的 REST 风格. 正如作者所说 REST 是一种架构风格,而非严格的标准,没必要在形式定义上去做过多真论,到底什么才是真正的 REST.

Web API设计方法论

- - 博客园_知识库
  英文原文: A Web API Design Methodology.    为 Web 设计、实现和维护 API 不仅仅是一项挑战;对很多公司来说,这是一项势在必行的任务. 本系列 将带领读者走过一段旅程,从为 API 确定业务用例到设计方法论,解决实现难题,并从长远的角度看待在 Web 上维护公共 API.

Java API 设计清单 « 友好的API

- - 东西
在设计Java API的时候总是有很多不同的规范和考量. 与任何复杂的事物一样,这项工作往往就是在考验我们思考的缜密程度. 就像飞行员起飞前的检查清单,这张清单将帮助软件设计者在设计Java API的过程中回忆起那些明确的或者不明确的规范. 本文也可以看作为“ API设计指南”这篇文章的附录. 我们还准备了一些前后比对的例子来展示这个列表如何帮助你理清设计需求,找出错误,识别糟糕的设计实践以及如何寻找改进的时机.

AT&T公布HTML5 Web应用API

- - HTML5研究小组
北京时间1月10日消息,据国外媒体报道,AT&T首席营销官大卫·克里斯托弗(David Christopher)今天在该公司第六届开发者峰会公布了面向HTML5应用的API(应用编程接口)平台API Catalog. HTML5应用可以在多种设备和移动操作系统上运行.   iPhone版Visual Voicemail将是AT&T的首款网络API.

HTML5 Web Speech API,让网站更有趣

- - SegmentFault 最新的文章
Web API 变得越来越丰富,其中一个值得注意的是 Web Speech API. 传统的网站只能“说”,这个API的出现,让网站能“倾听”用户. 这个功能已经开放了一系列的用法,非常棒. 在这篇文章中,我们将看一下这项技术和建议的用法,以及如何用它来增强用户体验的一些好例子. 声明:本技术比较前沿,目前该规范是W3C的“非官方编辑器的征求意见稿”(截至2014年6月6日).

API 设计二三事

- 烙饼 - 岁月如歌
所有程序员都是 API 设计者. 很认可 Dan Webb 的这句话. 近期刚好也有一些思考,总结分享下. jQuery 很优秀,原由之一就是其 API 具有很强的可预测性. 这样,不用详细阅读文档,根据直觉,就可以推测出 API 的一些高级用法,并且记忆深刻(因为是自己探索发现出来的). 我们可能会好奇,是什么让我们拥有这个“直觉”.

RESTful API 设计指南

- - 阮一峰的网络日志
网络应用程序,分为前端和后端两个部分. 当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备......). 因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信. 这导致API构架的流行,甚至出现 "API First"的设计思想. RESTful API是目前比较成熟的一套互联网应用程序的API设计理论.

API 接口设计规范

- - 掘金后端
这篇文章分享 API 接口设计规范,目的是提供给研发人员做参考. 规范是死的,人是活的,希望自己定的规范,不要被打脸. url?后面的参数,存放请求接口的参数数据. 请求头,存放公共参数、requestId、token、加密字段等. Body 体,存放请求接口的参数数据. 调用方需向服务方申请 appKey(请求时使用) 和 secretKey(加密时使用).

Flickr向开发者提供实时Web API

- 品味视界 - cnBeta.COM
Flickr今天向程序员推出了一个名叫Photo Hack Day的活动,释放了一批新的代码和API,让开发人员能够利用Flickr实时访问数据库从而构建新的应用,目前Flickr已经保有60亿张以上的图像. 新的API可以搜索每天上传的数以百万计照片并实时提供,这些数据还包含50多个机构例如美国宇航局,美国国会图书馆,美国和英国国家档案馆的更新.

2013年影响Web发展的五类API

- - 博客 - 伯乐在线
英文原文: 5 APIs that will transform the Web in 2013,编译: CSDN-张红月. 本文作者Alex MacCaw是一名JavaScript 程序员,O’Reilly作者,目前就职于Stripe. 他认为,在接下来的一年,Web领域将会有越来越多的储技术蜂拥而至.