写点什么

Web API 设计方法论

  • 2015-01-12
  • 本文字数:5754 字

    阅读完需:约 19 分钟

为 __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"等)的媒体类型很重要。有相当多可用的格式。

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

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

在这个例子中,我会以 HTML 为消息格式,并采用 HTTP 协议。HTML 有所有数据描述符所需的支持 (

2015-01-12 21:4420889
用户头像

发布了 45 篇内容, 共 23.9 次阅读, 收获喜欢 9 次。

关注

评论

发布
暂无评论
发现更多内容

anonymous匿名者场外交易系统APP软件开发

系统开发

从MongoID的生成讨论分布式唯一ID生成方案

行如风

雪花算法 分布式ID 全局唯一ID 流星算法

英特尔力邀150家产业大咖推动Evo严苛认证,打造PC界的奥斯卡

新闻科技资讯

快速接入 | 从 0 到 1 构建语音聊天室

拍乐云Pano

音视频 RTC 实时语音 语音聊天室 语聊房

高空立体云防控系统搭建,智能化平安小区建设方案

t13823115967

平安小区 智慧平安社区建设

字节二面跪拜“Redis源码”后,面试官直接推荐这份笔记!真是NB

比伯

Java 编程 架构 面试 程序人生

智慧仓储管理系统,是否能解决购物狂欢节后新一轮爆仓危机?

一只数据鲸鱼

物联网 数据可视化 智慧物流 智慧仓储

云视频技术领军人赵加雨:如何提升在线教育课堂互动体验

拍乐云Pano

音视频 在线教育 RTC 互动课堂 白板

星域母子币系统软件开发|星域母子币APP开发

系统开发

如何基于 SDK 快速开发一款IoT App 控制智能灯(iOS 版)

IoT云工坊

ios App 物联网 IoT sdk

扒开 SqlSession 的外衣

田维常

mybatis

生产环境全链路压测建设历程 21:某快递 A 股上市公司的生产压测案例之基于测试流量的混沌工程(故障演练)

数列科技杨德华

全链路压测 七日更

人工智能不过尔尔,基于Python3深度学习库Keras/TensorFlow打造属于自己的聊天机器人(ChatRobot)

刘悦的技术博客

人工智能 tensorflow chatbot 聊天机器人 keras

如何通过 Serverless 轻松识别验证码?

Serverless Devs

人工智能 Serverless 云原生

一线大厂开源三份JDK+Spring+Mybatis源码笔记

Java架构追梦

Java spring 源码 jdk mybatis

英特尔赵宏:从硬件创新到平台突破,PC的未来非常值得期待

新闻科技资讯

九环智能合约开发

V19927655815

APP开发

为什么要TDD(测试驱动开发)

sherlockq

敏捷开发 TDD 极限编程

从一个模糊词查询需求的处理方案讨论到一种极速匹配方案的实现

行如风

模糊匹配 双数组trie树 ahocorasick ac自动机 黑名单过滤

为什么说rollup比webpack更适合打包库

fengxianqi

大前端 Rollup webpack

抢先体验全新升级版Eternal Wallet!

Geek_c610c0

数字货币 数字货币钱包开发

没能进入大数据领域

escray

面试 面经

深入浅出 ZooKeeper

vivo互联网技术

zookeeper 分布式 ZAB

应急指挥中心平台搭建,移动可视化指挥解决方案

t13823115967

可视化数据分析搭建 应急指挥

什么是浮点数?

Kaito

计算机基础 浮点数

重磅|中国PostgreSQL分会与腾讯云战略合作协议签订

PostgreSQLChina

数据库 postgresql 软件 开源社区

直播中不可缺少的一环-rtmp直播推流

anyRTC开发者

音视频 WebRTC CDN RTC RTMP

移动生态盘点与HMS生态解析

华章IT

华为 Android Studio 移动开发 HMS

盘点 2020 | 10 天开发前台系统技术系列

老魚

CSS 大前端 全栈 js 盘点2020

Web API设计方法论_语言 & 开发_Mike Amundsen_InfoQ精选文章