APIs.json 发现格式, API经济的潜在引擎

最后更新于:2022-04-01 03:13:25

在API与微服务飞速发展的当今世界,如何在开发web或移动应用时、或者是对现有的系统进行集成时找到最合适的API,通常是一项乏味的任务。与之相对的是,许多API提供者为了让他们所有的最有价值的、以API驱动的资源能够为潜在的调用者所发现并方便地进行访问而绞尽脑汁。截至2014年底,市场上所存在的API目录也只有为数不多的几个,API提供者能够在此列出他们的API,而API调用者可以在此找到他们所需的API。虽然这种途径目前已经经过了一段时间的应用,但它是专门为了人类而设计的,其它应用程序与系统无法通过这种途径找到适合的API,并根据他们调用的API资源进行相应的决策, [TOC] ## APIs.json于2014年5月发布 在2014年5月, 作为一家API管理基础设施提供者,3Scale与API Evangelist共同合作,推出了一种机器可读的开放式API发现格式,名为**APIs.json**。**APIs.json**的目标是提供一种简单而通用的格式,可用于对API以及API运营的支持性元素进行索引。**APIs.json**的工作方式类似于[Sitemap XML](http://www.sitemaps.org/protocol.html)的格式,但它的设计目的不是对网站进行索引,而是对各种API进行索引,并将索引结果上传至一个[众所周知的地点](https://tools.ietf.org/html/rfc5785),API的提供者可以将他们的API资源的索引发布在此。 APIs.json的设计目标是为API提供者一个简单的方式以更新他们的API索引,同时也让其它搜索引擎、目标与API服务提供者访问本地索引,让该领域中的API资源可被发现。 ## 快速了解APIs.json **APIs.json**的定义总是由一些基础信息的描述开始,用以表示API的作者,并将描述信息放在文件的头信息中,这为调用者提供了关于API作者的一些描述参数,包括名称、描述、图片、标签、创建日期、最后修改日期、以及该**APIs.json**所发布的url。 ### 基本APIs.json指令集 ~~~ { "name": "API Evangelist", "description": "This is an inventory of APIs available as part of the API Evangelist network.", "image": "https://s3.amazonaws.com/kinlane-productions/api-evangelist/t-shirts/KL_InApiWeTrust-1000.png", "tags": [ "application programming interface", "API", "News", "Analysis" ], "created": "2014-04-07", "modified": "2014-07-09", "url": "http://apievangelist.com/*APIs.json*", "SpecificationVersion": "0.14", ... } ~~~ 接下来是**APIs.json**文件的核心部分,即API的集合。它让API提供者能够描述集合中的一个或多个API。与头信息中的参数相似,每个API都可以设置几个参数,用以对每个API进行描述,包括名称、描述、图片、标签、humanURL(用于让开发者进行访问,以了解该API更多信息的url地址),以及baseURL(机器将通过访问这个基本url以开始使用该API)。 ### APIs.json文件的核心 —— API集合 ~~~ ... "apis": [ { "name": "Analysis", "description": "Provides access to blog posts and analysis across the API Evangelist network.", "image": "https://s3.amazonaws.com/kinlane-productions/api-evangelist/t-shirts/KL_InApiWeTrust-1000.png", "humanURL": "http://developer.apievangelist.com", "baseURL": "http://api.apievangelist.com/definitions/Analysis", "tags": [ "blog", "industry", "analysis", "new", "API", "Application Programming Interface" ], ... } ] ... ~~~ 在定义了API的基本元数据集之后,properties集合让提供者可以定义其它希望引用的url。比较常见的作法是在**APIs.json**的开头部分定义四个属性:X-documentation、X-signup、X-pricing和X-tos。当然,你可以定义任何一种希望在API中使用的属性,但推荐的方式是先从这几个最基本的构建块开始,因为每个API调用者都会查找这些信息。 ### APIs.json中最基本的构建块属性 ~~~ ... "properties": [ { "type": "X-signup", "url": "https://apievangelist.3scale.net/" }, { "type": "Swagger", "url": "http://api.apievangelist.com/definitions/Analysis" }, { "type": "X-blog", "url": "http://developer.apievangelist.com/blog/" }, { "type": "X-apicommonsmanifest", "url": "https://raw.githubusercontent.com/kinlane/analysis-api/master/api-commons-manifest.json" } ], ... ~~~ 作为**APIs.json**集合的一部分,对它的整体描述将提供该API如何进行索引的细节,不过在**APIs.json**格式中的其它部分也可以加入联系方式、标签以及对其它相关**APIs.json**文件的引用。**APIs.json**的设计方式是成功一种将元数据与API运营进行挂钩的基本框架,同时作为一种高度可扩展的url类型格式,可以在必要时在其中加入任意的外部引用,用于完整地描述API运营的每一方面。 ## 不仅是一种发现格式 如果你在一群技术专家当中提起API发现这个话题,他们会很快地指出现有的一些API发现的解决方案,这些方案中通常会包括在API设计生命周期的早期阶段采用超媒体模式。作为这些现有的API发现方式的一种替代方案,**APIs.json**专注于对当前的、并且在不断发展中的API进行索引,而不管它属于超媒体、RESTful甚至是SOAP web service技术。在一个理想的世界中,API的设计者都应遵循设计原则的通用集,但现实是,我们所面对的是数以千计的“[雪花状](http://www.devx.com/blog/agile/avoid-integration-snowflakes-api-reuse.html)”API描述,它们存在于几乎每个在线业务部门的API中。 **APIs.json**不仅将API发现的人机对话形式扩展为多种不同的服务类型,并且已将功能延伸至API发现的技术之外。在多数现已发布的**APIs.json**文件中,它们首先提供了其API的一些通用的技术构建块,例如通过API Blueprint或Swagger等常见的API描述格式对API的表面进行描述。不仅如此,**APIs.json**文件还能够提供各种重要的业务元素,例如对文档、价格说明、API注册或帐号管理的引用。此外,**APIs.json**还能够用于记录在API运营方面一些更政策性的内容,例如频率限制、认证细节、服务条款以及隐私协议等等。以上所有这些功能综合在一起,再加上机器可读的访问功能,使得**APIs.json**索引成为API运营的技术、业务、以及政策构建块的入口。 ## 自托管的发现能力 虽然**APIs.json**文件多数情况下只用于单一的域名中(作为一个本地的API索引存在),但APIs.json文件中所包括的API可以分布于任意数量的公开网站或私有网站。这也意味着由APIs.json驱动的集合不仅能够为API提供索引,同时可以将它们聚合在一起,成为一个更有价值的集合,这种集成能力可用于交付特定并且定向的应用程序、设备以及系统集成功能。 (点击放大图像) [![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f43561d3422.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f43561d3422.png) Fitbit为[它的API](http://www.fitbit.com/apis.json)设计了专门的**APIs.json**文件,而HP同样通过[Link Creation Studio](https://s3-us-west-1.amazonaws.com/linkcreationstudio.com/developer/APIs.json)设计了**APIs.json**,这种做法对于成熟的API平台已很常见。这些**APIs.json**文件由各自的API所有者负责维护。而其它任何人,可能是一个API代理或是一个应用程序开发代理,都可以发布各自的第三方**APIs.json**文件,在其中聚合Fitbit的API以及Link Creation Studio的API,通过这种方式建立一个专用的API集合,可用于开发需要用到Fitbit数据的应用程序。不仅如此,它还能够提供链接以及图片管理资源,通过图片水印与QR码的方式,将各种不同的应用程序连接到真实的世界中。 ### APIs.json的工具 即使**APIs.json**是一种开放的格式,但如果没有现成的工具能够促成API的发现与探索,那么它对于API的提供者或调用者来说都是没什么价值的。考虑到这一点,人们所开发的第一个由**APIs.json**驱动的开源搜索工具为API的发现带来了一种不同的方式。这个工具本身就具备自己的API,并且将所有机器可读的**APIs.json**文件聚合到一个单一的、可以被公众所访问的API搜索引擎,[名为APIs.io](http://apis.io/)。 (点击放大图像) [![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4357096368.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4357096368.png) 在2015年,又有几家公司为其推出了一些相关特性: 1) 企业内部的API搜索引擎 2) 支持Google Chrome与Firefox浏览器的插件 3) 基于IDE的集合 4) 电子表格控制台与可连接性 这些特性都是基于**APIs.json**文件的。而这些特性只是对基于**APIs.json**开发的现有工具的快速了解,它们将辅助API提供者、调用者,以及它们的系统或应用程序,让它们在这个不断扩张的API世界中被发现,并且确实有许多API已经被成功地发现了。 除了用于开放工具的开发之外,**APIs.json**的潜能在运行时也得到了充分的表现。它不仅能够作为API搜索引擎、集成开发环境、或统一电子表格工具,也可以在任何一个应用程序中作为一个潜在的引擎,为可用的API终结点、认证细节、响应代码、底层所用的数据模型、API的许可选项、频率限制、价格,以及整个API集成中的任何一个重要方面提供重要的详细信息。 通过**APIs.json**,应用程序就能够基于API的[价格](http://api-pricing.apievangelist.com/)、可靠性、[许可](http://apicommons.org/)、[服务条款条目](http://api-questions.apievangelist.com/)等条件选择其底层的云存储提供商,甚至可以基于相同的条件,做出与消息发送、图片、视频或集成其它API等方面的决策。 ### 简单而强大的设计 **APIs.json**被设计为一种简单的、机器可读的格式,可以发布至一个人们所熟知的地方,为一个或多个API制作详细的索引。这些索引提供了非常有价值的元数据,能够为在API搜索引擎、IDE、电子表格以及其它任何工具、应用程序、设备以及系统集成做出实时的决策。**APIs.json**格式最初的设计是用于API发现,但它有很大的潜力成为API经济方面的一个潜在的引擎。 (点击放大图像) [![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f435723cfec.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f435723cfec.png) 对于API发现这一任务,你很容易将它看作一种临时性的体验。一旦找到一个API,就可以完成你的任务了,API的发现过程就此结束。但是,在现实中,在我们所创造出的这个永不停歇的数字世界中,这个过程是一而再再而三地不断发生的,我们将永远不停地继续寻找能够满足我们不断发展的需求的API。 伴随着这种API发现周期的出现,我们也需要更多的数据点,不仅是基于关键字的搜索,也不仅是SOAP或是REST、JSON或是XML风格的发现功能。我们将根据现实世界中的数据点进行API发现与应用方面的决策,它将对整合过程产生深远的影响,这些数据点包括价格、许可、可用性、稳定性、服务条款等等。我们极度渴望为这些API运营领域找到机器可读的描述以及各种工具,帮助我们实时地找到合适的API,并指导我们恰当地运用它。 **APIs.json**是一种仍在发展中的支持工具,可作为那些有价值的、机器可读的数据点的基本框架,次世代的API发现工具将打通API的运营。不仅如此,从发现、设计到管理、测试以及监控,它还能够让API在整个生命周期的每一阶段都做到可访问性。它为这个虚拟引擎描绘了一副蓝图,以驱动整个API经济的发展,而不再局限于技术领域。对于从2015开始建立的各个业务部门的API,它将以最恰当的方式处理它们的业务以及政策。 ## 关于作者 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f435ecd91f5.jpg) **Kin Lane** 从上世纪80年代后期就开始进行数据库方面的工作,最近五年来则完全专注于应用程序编程接口,也就是人们所熟知的API方面的技术、业务与政策。Kin的工作是让技术专家以及“普通人”了解数据的可移植性、互操作性、安全性以及隐私方面的重要性,其范围涵盖了个人以及公司所依赖的web以及移动应用平台。他的客户包括创业公司与一般企业,并且还作为一名前任的“总统创新之友”(Presidential Innovation Fellow)计划的成员为政府项目出谋划策。你可以关注他的博客APIEvangelist.com,以及Twitter帐号@kinlane。 **查看英文原文:**[The APIs.json Discovery Format: Potential Engine in the API Economy](http://www.infoq.com/articles/apis-json-discovery-format)
';

RAML的强大功能

最后更新于:2022-04-01 03:13:23

RAML的全称是[RESTful API建模语言](http://raml.org/spec.html),这是一种基于[YAML](http://yaml.org/)格式的新规范,因此机器与人类都能够轻易地理解其中的内容。但RAML的目的不仅仅在于创建更易于理解的规范(你可以将这一工作指派给文档团队,他们会做得更好)而已。RAML的设计者[Uri Sarid](https://twitter.com/usarid)希望使用者能够打破固有的思维,在开始编写代码之前以一种全新的方式对API进行建模。 [TOC] [Roy Fielding](http://roy.gbiv.com/)博士在他的博客[Untangled](http://roy.gbiv.com/untangled/)中指出,现在的人们总有一种倾向,他们只考虑短期的设计,目光只能看到我们所知的、我们目前所想的内容。 REST风格的发明者Roy Fielding表示:“很不幸,人们很善于处理短期的设计,但对于长期的设计通常就束手无策了。” 设计API的一大挑战在于,API通常都会存在较长的一段时间,有可能会存在数年之久。毕竟,API的设计需要开发者投入大量的精力,但同样对于客户来说也是一种极大的投入,因为客户也依赖于这些API,需要基于它们进行开发。从2009年起,Uri开始思考如何解决API的长期设计的挑战,他希望能够找到一种工具,让设计者只需几行代码就能够对API进行建模(或设计),然后快速地生成一个原型,让全球的开发者都能够尝试你的原型并提供反馈。在2013年,随着RAML 0.8的发布,他的梦想终于变成了现实。 自那时起,人们对于RAML的兴趣就在不断地升温。无论是大型企业还是小公司,他们都开始意识到了RAML所带来的益处:包括以一种人类可读的格式设计API、在设计时就看到这些API将怎样工作、并且能够为API创建一个活动的、全功能的示例,让开发者能够简单地通过点击按键,对这个API发起实际的调用。 [![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f434c323d71.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f434c323d71.png) > **提示** > 所有的RAML工具都是开源的,可以从[http://RAML.org/projects](http://raml.org/projects)免费下载。我的雇主MuleSoft还提供了这些工具的免费托管版本,你可以从[AnyPoint Platform for APIs](http://anypoint.mulesoft.com/apiplatform/)平台试用这些工具。 ## API契约的设计周期 但是,仅仅简单地创建一个原型是不够的。MuleSoft创建了一种API契约设计周期图,这一设计的前提在于API不仅仅是机器之间的一种契约,同样也是提供商与用户之间的一种契约。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f434c45d699.png) 这也意味着,在设计与创建原型之后,开发API的公司需要找到一种方式以共享他们的API,并从使用者那里获取反馈。这些有价值的反馈能够让公司找到设计中的缺陷,例如数据或结构中的不一致性,以及API中的一些令人困惑之处。在这一阶段及时发现设计中的问题非常关键,因为一旦你的API发布之后需要修改,那么在大多数情况下都会破坏向后兼容性,而这将影响API的使用。 提示 这一周期同样也是[规范驱动开发](http://www.mikestowe.com/2014/11/what-is-spec-driven-development.php)(Spec Driven Development)过程的基础。 ### API Console与API Notebook 为了实现这一设计周期,又出现了两种工具:即API Console与API Notebook。API Console与其它API控制台的作用很相似,例如Mashery的[IO Docs](http://www.mashery.com/product/io-docs)与[Swagger](http://swagger.io/),它提供了一个可进行文档工作的交互式环境,让开发者输入数据和发起调用请求。这意味着开发者在设计API原型的同时,也能够快速地看到可用的资源与方法,并且立即进行测试,以获得第一时间的验证结果。同时,一旦你的API发布之后,除了静态文档之外,你也能够发布交互式的文档,让开发者在一个相当简单的界面中试用这些API,并对API调用进行调试。 另一方面,[API Notebook](http://apinotebook.com/)的交互性与探索性更进一步,它能够让开发者使用JavaScript去调用你的(以及其他人的)API。在API Notebook中还能够对数据进行各种操作,通过实际应用中的用例观察它的运作。也就是说,开发者能够通过用例测试他们的原型,所需的只是编写几行JavaScript而已。 举例来说,在下面这张截图中,用户能够连接到[Instagram的API](https://instagram.com/developer/),通过OAuth进行验证,并尝试搜索带有“kitten”这个标签的图片,一步一步完成设计过程。 (点击放大图像) [![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f434c9622be.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f434c9622be.png) 但作为一个RAML工具,API Notebook真正强大的地方在于你可以为API的使用者创建用例,让他们自己进行走察。此外,你所创建的用例场景可以用于原型的设计以及发布于生产环境的API,并且你的调用者也能够通过markdown语法创建自己的Notebook。这样一来,你的使用者就能够共享bug与用例的信息,以获得更好的反馈与支持,并且无需共享任何私有的代码,也无需走查整个应用程序。 这个特性很简单,但它却让你的使用者不必将大量的精力用于寻找问题的根源,同时也让你的支持团队能够快速地重现这些错误,而无需猜测这些问题是否是由客户端代码所引起的。 等到你收集了这些反馈之后,就能够对你的设计进行调整,并决定该设计是否已经可以在生产环境中应用了。它的另一个益处在于,当你的API已经准备好上线时,你就能够在生产环境中使用这两个优秀的工具了,正如上文所说的那样。 为了帮助你的API顺利上线,可以在社区中找到许多其它实用的工具,包括用于生成API的相应代码以及对API进行测试的工具,例如[Abao](https://github.com/cybertk/abao)。除了API Console与the API Notebook之外,还有大量的工具能够帮助你进行文档化工作,包括[RAML to HTML](https://github.com/kevinrenskers/raml2html),它能够生成一个单一的HTML文件(与API console相类似)作为文档。以及[使用PHP的RAML2HTML](http://www.mikestowe.com/2014/05/raml-2-html.php)工具,这个脚本能够创建一个完整的、多页面的文档网站: (点击放大图像) [![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f434cbe6a91.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f434cbe6a91.png) 这个脚本可以进行充分的自定义,可以修改全局的模板甚至是内容块,以满足你对于文档的需求。 此外,还有许多工具能够对RAML进行解析,可以将你的API规范整合到你的自定义应用中,而不关心你的应用是用Ruby、PHP、JavaScript、.NET、Python还是Java编写的。 ## 人类可读 由于RAML被设计为一种人类可读的格式,因此通过它开始设计一个全新的API或定义一个现有的API都非常简单。虽然你可以在任意一种编辑器中创建RAML,但最方便的方式还是使用在线的API设计器,或是专门为[Sublime](https://github.com/mulesoft/raml-sublime-plugin)或[Visual Studio](https://github.com/mulesoft-labs/raml-dotnet-tools)等IDE所设计的插件(两者都可以在[RAML.org/projects](http://raml.org/projects)中找到),你可以在设计过程中充分利用它们的工具提示、自动完成以及实时校验功能,这使得整个过程更加简便。 开始设计时,首先创建一个包含以下内容的RAML文件: ~~~ #%RAML 0.8 title: This is My API baseUri: http://api.domain.com version: 1 ~~~ 在以上代码中,我们首先声明这是一个RAML规范,它对应RAML 0.8(版本1很快就会发布了),并声明API的标题、基本URI、以及这个API的版本号(这个示例中的API是版本1)。 在RAML中声明资源非常简单,只需使用/resourceName格式。而添加方法也同样便捷,只需引用相应的HTTP谓词即可: ~~~ #%RAML 0.8 title: This is My API baseUri: http://api.domain.com version: 1 /resource1: get: description: This gets the collection of resource1 post: description: This adds a new item to the collection ~~~ RAML让你能够定义多种相应,返回不同的状态码、头信息以及响应体。例如: ~~~ #%RAML 0.8 title: This is My API baseUri: http://api.domain.com version: 1 /resource1: get: responses: 200: headers: cache-control: example: | public, no-cache, no-store body: application/json: example: | {"name":"Michael Stowe"} application/xml: example: | <name>Michael Stowe</name> 400: #... 401: #... ~~~ RAML本身还有大量的其它特性,让你通过schema与参数定义完整的API。它还允许你使用资源嵌套(与Saas中进行CSS嵌套的方法相近)、文件引用(可以引用多个文件,以保持规范的易读性和易组织性),甚至是变量或属性的设置,从而在整个规范中保持一致性。 举例来说,你可以在规范中按以下方式利用这些特性: ~~~ #%RAML 0.8 title: This is My API baseUri: http://api.domain.com version: 1 /resource1: get: responses: 200: body: application/json: schema: | { "type": "object", "$schema": "http://json-schema.org/draft-03/schema", "id": "http://jsonschema.net", "required": true, "properties": { "firstName": { "type": "string", "required": true }, "lastName": { "type": "string", "required": true, "minLength": 3, "maxLength": 36 } } } /sub-resource: get: queryParameters: firstName: description: "the user’s first name" example: John required: true type: string ~~~ ## 对开发者十分友好 RAML的优点不仅在于简单的格式与丰富的工具,它还能够让开发者应用编码的最佳实践,例如模式与重用代码。这不仅能够极大地减少开发者的工作,还能够促使API在不同的资源与方法中保持统一性。虽然你总是能够抽象出一套schema,以保持规范的良好组织,或是通过“!include”命令引入schema、示例与其它RAML代码片段,但RAML还提供了两个额外的实用与独特的模板特性:即traits与resourceTypes。 ### 通过traits定义通用属性 RAML的traits特性允许你为方法(GET、PUT、POST、PATCH、DELETE等等)定义通用的属性(或traits),例如它们是否可过滤、可搜索或是可分页。 在创建trait时,你实际上是创建了一份模板,它能够通过接受参数为方法提供属性,只需几行代码就能够完成。同时为你所需的trait提供了最大程度的灵活性与自定义能力: ~~~ traits: -searchable: queryParameters: query: description: | JSON array [{"field1","value1","operator1"},…] <<description> example: | <<example>> /people: get: is: [searchable: {description: "search by location name", example: "[\"firstName\"\,\"Michael\",\"like\"]"}] ~~~ ### 通过ResourceTypes为资源定义模板 此外,与traits相似,resourceTypes也允许你为资源本身创建模板,以此调用通用的方法与响应。打个比方,对于Collection这种资源类型来说,你可能会大量用到POST与GET方法,并且通常会返回200、201或400等状态码。只要将它定义为一种resourceType,你就能够通过两行代码就完成调用,而无需为你所创建的每种资源都加入相同的方法与状态码。 ~~~ resourceTypes: - collection: description: Collection of available <<resourcePathName>> get: description: Get a list of <<resourcePathName>>. responses: 200: body: application/json: example: | <<responseVariable>> 400: #... 401: #... /people: type: collection: responseVariable: | { "name" : "Michael Stowe", "company" : "MuleSoft", } ~~~ 你甚至可以在resourceTypes中定义可选的方法,只需为该方法加上一个问号(?)即可。这种可选方法只有在定义了该方法的资源中才会被引入,这就为你赋予了更大的灵活性。 提示 RAML允许你创建任意数目的resourceTypes和traits。不过,如果你发现你所定义的resourceTypes超过两种(collection与item),那么你可能要评估一下你的API,以确保对这些resourceTypes的使用方式是一致的。你可以在[RAML 200教程](http://raml.org/docs-200.html)中了解到更多的知识。 ### 自动生成SDK RAML还可以通过其它工具为开发者节省宝贵的时间与资源,比方说可以通过[APImatic.io](https://apimatic.io/)等提供者为用户提供自动生成多种语言的SDK的能力。使用APImatic.io无需手动编写这些SDK,也不必依赖于社区保持它们的更新,它可以让你简单的导入RAML规范,随后生成面向Java、Python、PHP、Ruby、AngularJS、iOS和 Windows等平台和语言的SDK。 ### 超越代码 RAML正逐渐成为API规范方面的领头人之一,与Swagger和API Blueprint并驾齐驱。现如今已有越来越多的API方案提供者支持这一格式了(包括管理与工具等方面)。 为了加快发展的脚步,同时确保规范的完整性,在RAML于2013年问世的同时,一个由API领域驱动的工作小组也一并成立了。该工作小组将负责指正RAML的发展方向,确保它将继续遵循最佳实践,并符合业界的需求。目前,该工作小组由来自MuleSoft、AngularJS、Intuit、Airware、PayPal、API Science、Akana和Cisco的代表所组成。 RAML的出现不过一年多的时间,目前1.0版本的工作还在进行之中,新版本的目标是提供更多的功能,并且更好地满足业界的需求,同时推进API的最佳实践。当然,它也面临着一些挑战,包括如何定义与描述超媒体,这一点在所有的主要规范中都被提及。 ## 如何为克服这些挑战作出贡献 开源社区的优点就体现在这里,新的点子总是能够找到立足之处。每个有志之士都可以通过访问[RAML.org](http://raml.org/)加入这一项目,并且在[GitHub](https://github.com/raml-org/raml-spec)上贡献独创的工具,或是创建规范的分支。毕竟,RAML的强大之处不仅仅在于目前它所实现的部分,即通过一个单一数据源,通过可视化的方式进行API的设计、创建原型、构建、共享以及进行文档化,而在于它将如何对未来产生持续性的影响。 ## 关于作者 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f434cda4d46.jpg) **Michael Stowe****是一位****RAML****的**忠实支持者,他在创建应用方面已有超过10年的经验,所涉及的领域包括法规实施、非盈利项目、工业,并且加入了多个开源项目。他目前在MuleSoft担任开发者管理经理,作为工作的一部分,他经常在各种技术型会议上进行RAML以及API设计方面的演讲,包括API Con、API Strategy and Design以及API World等等。由Michael所编著的一本关于REST API设计的书籍即将面世。你可以通过@mikegstowe关注他的Twitter,了解他的最新帖子。你也可以通过[http://www.mikestowe.com](http://www.mikestowe.com/)观看他所做的演讲,并了解他的技术思想。 **查看英文原文:**[The Power of RAML](http://www.infoq.com/articles/power-of-raml)
';

通过Swagger进行API设计,与Tony Tam的一次对话

最后更新于:2022-04-01 03:13:21

要找到[Tony Tam](https://www.linkedin.com/in/tonytam)真不是一件容易的事,他总是日理万机难以抽身。人们对于Tam的了解多数来自于在他的影响下出现的[Swagger](http://swagger.io/),这是目前最流行的一种Web API规范框架。Tam同时也是[Reverb](https://helloreverb.com/about/)的创始人,这是一家进行内容分析与推荐业务的公司。他还是[Wordnik](https://wordnik.com/about)的奠基人之一,这是世界上最大的在线英文辞典。自从他在加州大学圣塔芭芭拉分校与圣塔克拉拉大学就读以来,他已经参与了数家公司的创立。他甚至还拥有一项基于内容获取创建用户档案技术的[专利技术](http://www.google.com/patents/US8838589)。如今Reverb已经被NDN([newsinc.com](http://newsinc.com/))所收购,而Tam正在新兴技术部副总裁这个新职位上忙得不亦乐乎。 这段时间对于Swagger框架来说也是一个繁忙的季节,在Swagger的开放[工作小组](https://github.com/swagger-api/swagger-spec)(自2014年5月成立)的不懈努力下,Swagger 2.0终于在2014年9月正式发布了。我们的采访是在2015年3月进行的,此时距2.0的工作启动还不足一年。此外,不久之前Reverb刚刚宣布Swagger规范未来的发展将[转交](http://developers-blog.helloreverb.com/swagger-smartbear/)给[SmartBear](http://smartbear.com/about-us/),这是一家位于马萨诸塞州的软件工具公司。 人们对于近期的一些事件还记忆犹新,因此我们的对话将从2009年Swagger框架启动时说起。 **Mike Amundsen****:Swagger API****框架原本并不是一个公开的项目,而是在Reverb****(当时还称为Wordnik****)内部开发的一个项目,这可能会让人们感到吃惊。你能为我们介绍一下Swagger****项目刚刚成立时的一些情况吗?** > **Tony Tam:**启动Swagger这个项目的目的是克服当时在Wordnik的工作中所遇到的一些真实的挑战。当时我们正在创建REST API,由我们的付费客户进行调用。在公司内部,我们为系统打造了一个统一的API接口,希望根据我们与每个客户之间的协定为他们开放权限。也就是说在文档中只记录他们有权限使用的操作。此外,客户还要求我们向其提供原生的SDK。 **Mike****:因此为了解决创建大量的自定义接口与文档的麻烦,你们就设计了Swagger****是吗?** > **Tony:**是的,而且我也很讨厌重复地做一些完全相同的事。我们当时想到了一个点子,就是为我们的REST API创建一个泛用的JSON模型,它能够反映出调用者有权限进行哪些操作。它成为了我们的代码生成器的输入模型。之后,在我们办公室中有一位非常聪明的开发者指出,我们应当如何使用这一模型以打造一个交互式文档的UI,它后来就成为了Wordnik开发者网站。正是通过JSON模型与交互式文档的概念相结合,才有了我们如今称为Swagger这一框架的出现。 **Mike****:那么,Swagger****又是怎样一步一步成为如今被广泛使用的一个面向公众的工具呢?** > **Tony:**在我们将交互式UI发布至[http://developer.wordnik.com](http://developer.wordnik.com/)之后,我们对于这一项目的兴趣也是水涨船高,并最终将它的UI、服务端集成以及代码生成部分全部进行了开源。 > > 这个项目的初始目标是处理一些现实世界中遇到的挑战,虽说它目前的发展已经远远超越了它起初的模样,但核心的思想依然是为API定义一个一致的、可预测的模型。 **Mike****:你从2009****年开始从事Swagger****的开发,而Swagger 2.0****版本刚刚在2014****年秋季[发布](http://developers-blog.helloreverb.com/swagger-has-turned-2-0/)****。发布新版本的主要动力是什么,Swagger****在新版本中又迎来了哪些变化呢?** > **Tony:**经过了多年的参与之后,你肯定已经清楚哪些方式行得通、哪些行不通。在之前版本中有一些结构化方面的问题,它会造成大量的支持问题,此外我们也希望在Swagger规范中对JSON格式的schema进行更好的支持。我们还希望让定义变得更简洁,并且便于在建模工具中进行编辑。 **Mike****:那么,对于Swagger****用户来说,“2.0****”是一个破坏性的版本吗?** > **Tony:**我们在过去三年间发布了Swagger的1.0、1.1与 1.2版本,它们与原始的设计相比只有一些小幅度的改进。而这一次,我们借此机会对Swagger规范进行了一次较大的改动。 > > 当然,我们在每个版本中都尽量做到让升级工作变得更简单。即使Swagger 2.0中有如此多的变化,但服务端工具、UI与代码生成模板依然具有良好的兼容性。一般情况下只需对依赖进行相应的升级就可以了。 **Mike****:Swagger 2.0****中的一个新特性是允许定义扩展。为什么要加入这一特性?是否能够举例说明一下API****开发者应当如何使用这些扩展?** > **Tony:**这个特性推动的动力来自于以下几点。 > > 首先,我们并不想把所有可能的特性都塞到这个规范中去。先前曾有人建议将调用频度限制的功能也加到规范中,但这一特性很难实现泛用性,由于大多数用户都不会在意这一特性,因此我们不想因为它而污染了这一规范。 > > 其次,我们从Swagger的最初几个版本中学到了一个经验:如果没有一种简单而健壮的校验机制,那么很容易就会写出无效的规范。我们最终选择了JSON Schema校验工具,并将这一工具直接加入Swagger-UI项目中。这是我们的工具集中非常重要的一部分,它能够帮助开发者编写有效的Swagger定义。 > > 要从规范中移除结构化的限制,同时要保留一种健壮的校验工具,实现这一点非常困难。我们所选择的方式是在规范中通过使用一种扩展前缀获得更大的灵活性,开发者能够让Swagger产生更大的实用性。有些非常实用的扩展有可能会在下个版本的Swagger中“升级”为标准特性。 **Mike****:Swagger 2.0****的发布似乎得到了来自社区的极大影响,包括大量的变更请求与新特性。你如何决定在2.0****中加入哪些变更呢?** > **Tony:**Swagger 2.0规范中包含了所有我们认为有意义的特性,这个项目不是由时间线或某个特性集所驱动的。我们获取了大量有价值的建议并认真聆听。最终,我们基于规范的核心目标做出决策,而不是尝试同时解决所有人的问题,后者只会使你的项目变成一个大泥巴球。 **Mike****:有一个特性请求最终没有出现在2.0****版本中,即对于超媒体描述的支持。但在Github****上,这一**[**问题**](https://github.com/swagger-api/swagger-core/issues/97#event-159248864)**处于已关闭状态,并描述为“不在设计考虑中”。超媒体在API****设计的地位正在不断提高,为什么你认为它不应出现在2.0****版本中呢?你认为它有可能会出现在今后的版本中吗?** > **Tony:**这个提交信息本身已经说得很清楚了,Swagger的这个版本并非是为了超媒体而存在的,或许它在某种程度上确实有存在的意义,但即使加入对Hypermedia的支持,也无法实现Swagger目前的任何目标。或许它们之间确实有些格格不入,但我对此也不是非常确定。 **Mike****:虽然Swagger****出现至今还不到5****年时间,但它在Web API****的开发者中已经有了大量的粉丝。它的足迹似乎比其它的一些API****设计更为深刻,包括WSDL****、WADL****、AtomSvc****以及其它。你认为产生这一情况的原因是什么?是什么原因让Swagger****得到了如此**[**广泛**](http://www.javaworld.com/article/2607177/java-app-dev/swagger-aims-to-become-the-de-facto-standard-for-apis.html)**的应用。** > **Tony:**在我看来,Swagger能够得到这样的成功,其背后有一些关键的因素。首先,它确实解决了一些常见的问题。你是否能够以一种简便的方式为老板展示你的API?你怎样让客户试用它?Swagger UI能够帮助描述这个API的功能,以及它的运作方式。 > > 其次,Swagger规范本身足够简单,开发者在每一种主流的编程语言中都编写过对它的集成。像Swagger Inc.这样的企业能够负责整个API的工具链,而使用我们的工具的开发者已经不下一万,他们编写了各种不同的集成方式。能够跨语言以及跨框架对Swagger的发展非常重要。 > > 最后一点,Swagger的成长经历与众不同,它不是通过市场宣传,或是在某个充斥着flash的网站上展示各种logo而兴起的。它的流行完全来自于开发者这一草根阶层自发的支持。 **Mike****:在撰写本文时,目前最常用的三个API****描述框架应当要属Swagger****、RAML****和Apiary Blueprint****了。你认为Swagger****与其它两种格式相比有什么优势?开发者会**[**基于**](http://www.mikestowe.com/2014/07/raml-vs-swagger-vs-api-blueprint.php)**哪些因素而**[**选择**](http://apievangelist.com/2014/01/16/api-design-do-you-swagger-blueprint-or-raml/)**其中一种格式?** > **Tony:**我在这里可以提几点。这些规范的功能有着明显的不同之处,想要同时支持这三种规范而又不失通用性是不太可能的,因为你无法将某种规范简单地转换成另一种。这就像要你设计一种适合任意尺寸的汽车防尘罩,能够同时适合你的保时捷与房车一样不现实。 > > Swagger在所有这些描述格式中的结构是最多的,它的核心目标是能够为强类型语言实现操作与模型的描述,这也意味着我们能够在API中提供足够的元数据信息,以生成原生的C++客户端。 **Mike****:那么,Swagger****是不是一种“严格”的格式,让开发者能够通过它学到创建API****的“正确方式”呢?** > **Tony:**Swagger并没有让开发者强制使用一种单一的工作流,它并不强制你选择自顶向下或是自底向上式的编码风格。对于其它格式来说,这确实是一个不可避免的抉择,因为它们对于工作流有严格的规定。 我想大多数开发者在选择描述格式时都会考虑到他们所使用的编程语言。如果某种格式没有符合你的编程语言的实现,你很可能会另请高明。 **Mike****:有一句话你经常**[**挂在嘴边**](http://www.javaworld.com/article/2607177/java-app-dev/swagger-aims-to-become-the-de-facto-standard-for-apis.html)**,在创建Swagger****时,你希望能够避免“CORBA****问题”。CORBA****问题指的是什么?你在创建Swagger****时又是怎样避免这一问题的呢?** > **Tony:**在我看来,CORBA问题就是指“为所有人设计”。如果你希望通过某个规范解决每个人的问题,那你肯定无法得到一个成功的规范。这就像设计界中的人所说的一样,“如果你将所有美丽的颜色混合在一起,只会得到一个肮脏的颜色”。这一点对于软件设计来说也一样,当你在设计例如Swagger这样的产品时,对于它的功能,必须以一种干净的、清晰的方式进行设计。当设计走上正轨时,就有许多的改进空间,但一切前提在于要把握好方向。 **Mike****:SmartBear****在Swagger****的发展中扮演了怎样的角色,为什么他们会在这个节骨眼上**[**选择**](http://developers-blog.helloreverb.com/swagger-smartbear/)**带领Swagger****今后的发展?** > **Tony:**SmartBear是最早一批将Swagger整合到他们的工具中的软件商之一。我们已经合作了很长一段时间,在API这一领域中,他们最适合领导Swagger的发展。他们将通过正确的途径打造开放的规范、工具以及社区。他们很清楚地看到,即使对于以Swagger为基础打造的商业产品来说,整个业界也能够得益于一个一致的API模型。SmartBear在API测试领域已经浸淫多年,他们在API设计方面的声望很可能已超越了其它的公司。 **Mike****:如今SmartBear****即将接管Swagger****的发展,那么你在这一规范的未来发展中又将扮演什么样的角色?** > **Tony:**我当然也在计划继续为这一项目做出自己的贡献。对于需要这一规范的人来说,我们将推出更多的资源与更好的支持,我也将继续工具链与规范方面的工作。 **Mike****:Leonard Richardson****将标准的发展描述为**[**一种连续的发展**](http://my.safaribooksonline.com/book/web-development/9781449359713/introduction/_understanding_standards_html)**,从法令到个人、从个人到企业、再从企业到开放。第一阶段的法令就是得到共识的行为,而最后阶段则是标准委员会的工作成果,例如W3C****、IETF****、OASIS****等等。按照Leonard****的评估来看,Swagger****创立时还是一种应用于你的公司的个人标准,然后很快成为了一个企业标准,得到了大量的组织的使用。在你看来,Swagger****能否在短期内成为一个开放标准呢?** > **Tony:**我们正在为Swagger规范创建正确的治理结构,这个过程将是公开的,问题只在于这个结构需要有多正式。我预计当分析过程结束后,就应当能够得到正确的结论了。 **Mike****:还有没有什么我还没有问及的问题,是你打算与读者分享的?** > **Tony:**我想你的问题已经基本涵盖了所有的部分,感谢你的宝贵时间。 ## 关于受访者 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4347343e39.jpg) **Tony Tam**是NDN的新兴技术部门的副总裁,同时也是工程部门的执行副总裁,负责协助全公司的技术问题。在加入NDN之前,Tony曾是Reverb的创始人与CEO,他在当时领导着网站的创新词汇导航系统的开发工作。他是MongoDB Masters小组成员之一,并且领导着Swagger API框架的开源工作。在加入Reverb之前,他曾是Think Passenger的创始人,兼任工程部门的高级副总裁,这是一家设计客户协作软件的供应商。在那之前,他曾在Composite Software担任工程师主管,帮助公司开发了第一代与第二代查询处理引擎,并领导着具有专利权的,基于成本的联合查询优化器这一产品的研究与实现。他也曾在Galileo Labs的生物信息小组领导软件开发工作,这是一个基于硅谷的新药研发公司。 **查看英文原文:**[APIs with Swagger : An Interview with Reverb’s Tony Tam](http://www.infoq.com/articles/swagger-interview-tony-tam)
';

从涂鸦到发布 —— 理解API的设计过程

最后更新于:2022-04-01 03:13:19

要想设计出可以正常运行的Web API,对基于web的应用的基本理解是一个良好的基础。但如果你的目标是创建出优秀的API,那么仅凭这一点还远远不够。设计优秀的API是一个艰难的过程,如果它恰巧是你当前的工作任务,那么你很可能会感到手足无措。 不过,优秀的设计绝对是可以实现的。本文所描述的流程将帮助你获得成功,我们将共同研究什么是优秀的设计,以及迭代式的流程如何帮助我们实现这一目标。我们还将叙述设计的三个重要阶段:草图设计、原型设计以及实现,同时还将介绍一些能够让你的工作变得更轻松的工具。 [TOC] ## 优秀的API设计来自于迭代过程 在开始设计API之前,我们必须理解它的目的。在你手动设计之前,你应当了解为什么要设计这个API,如果在这方面[需要](https://medium.com/@medjawii/5-ways-an-api-is-more-than-an-api-bddcdb0517ca)[帮助](http://101.apievangelist.com/),有[许多](http://www.slideshare.net/jmusser/j-musser-apibizmodels2013)[现成](http://www.infoq.com/articles/web-apis-business-perspective)[的资料](http://www.fabernovel.com/work/6-reasons-why-apis-are-reshaping-your-business/)可以参考。不过,定义你的动机仅仅是第一步,真正的诀窍在于直到实现为止,始终保持进行正确的设计决策。 成功的API设计意味着要设计出一种接口,让它的使用方式符合它的目的。作为API设计者来说,我们所做的每个决策都会影响到产品的成败。设计过程中需要做出一些重大的决策,例如API所使用的传输协议、或它所支持的消息格式。但除此之外,还有许多相关的次要决定,例如接口的控制、名称、关联以及次序。而当你将所有的决策集中在一起时,它们将带动API的使用模式。如果你能够做到每个决定都是正确的,那么这种模式将对API产生完美的支持与促进作用。 如果你要做出一个正确的设计决策,很可能会先做出一个错误的决策,并从中吸取经验教训。实际上,你很可能会在多次犯错之后才能够接近正确的决策。这也正是迭代的关键所在,因为没有人能够做到一次成功,但只要有足够的机会,你就能够做到接近完美。 通过迭代方式进行API设计,这一点说起来容易,但在实际应用中做到这一点并不简单。我们所面临的一个常见的挑战在于,在某个API发布之后再进行变更是非常困难的。事实上,对一个使用中的API进行变更的代价很大,并且伴随着很大的风险。或者借用Joshua Bloch的说法:“[公开的API就像钻石,它是永恒不变的。](http://www.infoq.com/articles/API-Design-Joshua-Bloch)” 处理这一问题的一种方式是在每次变更时不要破坏现有的接口,这是一种好习惯,也是优秀API设计的一个主要原则。但有些时候,破坏性的变更是不可避免的,而基本层面的设计变更尤其具有侵略性。 换种思路,我们应当在接口发布之前就做好这些变更。在理想的情况下,在变更的代价变得高昂之前,就应该消除易用性与设计方面的问题。当时,只有在首次发布之前做到尽早开始迭代,并保持频繁的迭代,才能够找到并修复这些问题。 ## 迭代式的设计过程 在每一次迭代中,我们都得到了一次对设计候选按其使用情况进行评估的机会。举例来说,开发者是否能够通过使用我们创建的产品实现他的工作目标?这个接口真的能够实现吗?如果我们要求他人使用这个API,他们又会有什么样的感受? 通过设计与实现多个接口而不发布它们,应该能够实现最佳的API设计。通过对每个接口进行审查与测试,我们将对于如何改进最终产品具有良好的洞察力。 但是在实践中,这种壮观的迭代式设计是不可能实现的。没有几个人能有足够的时间、金钱或耐心去不断地设计与实现一个个可以运行的API。对于任何具有一定复杂度的接口来说,这种方式的迭代式设计会占用你过多的时间。 一个更合理的方式是在设计过程的早期就进行迭代,这些早期的设计应当具有足够的细节,可展现改进的最佳时机,但又无需过度设计而导致实现的困难。随着时间的推移,我们可以逐步地增加细节度(或保真度),并最终得到一个完整的实现。 这种逐步推进的设计过程在设计界已经非常流行了,它通常被分解为三个重要的阶段: 1. 草图设计 2. 原型设计 3. 实现 ### 草图设计的强大作用 草图设计是设计方面的一种普遍行为。著名建筑师[Frank Gehry](http://en.wikipedia.org/wiki/Frank_Gehry)的草图可谓天下闻名,以至于诞生了一部专门描述这些草图的[电影](http://www.pbs.org/wnet/americanmasters/episodes/frank-gehry/sketches-of-frank-gehry/602/)。他的许多建筑项目都是从在一叠纸上所画的一系列草图开始的。Gehry总会画上几百张这样的草图,每一次都向良好的设计更靠近一步。 交互设计师[Bill Verplank](http://en.wikipedia.org/wiki/Bill_Verplank)将草图设计描述为[设计过程中必不可少的第一步](http://www.billverplank.com/IxDSketchBook.pdf)。[Bill Buxton](http://en.wikipedia.org/wiki/Bill_Buxton)还专门写了一整本书,用以介绍草图设计方法对用户体验设计的价值,并认为它的关键特征在于它的可弃性、而且在所有探索方式中是成本最低的一种。 将草图设计过程包含在API设计过程的早期阶段,让我们有机会体验接口的概念模型。这不仅是一次定义我们脑中已有的想法的好机会,也让我们有机会探索新的道路,并且提出“如果……会怎么样?”这样的问题,并逐步走向真正的创新。 优秀的草图应当是易于创建、并且可以任意丢弃的。如果创建这些草图花费了许多时间、或是难度太高,那么你就难以丢弃它们。这种可弃性非常重要,它让我们有机会承受住风险。 我们可以通过草图设计尝试不同类型的接口风格,并捉住那些在我们脑海中时而闪现的抽象概念。一旦这些思想具体化,我们就能够对它们进行审查及讨论。在过程中决定我们喜欢或是不喜欢某个特定的概念,然后在消化了这些知识后再次启动这一过程,并绘制新的草图。 对于设计团队之外的用户来说,他们很少会对草图进行评估。不仅是因为过早地对假设进行验证是没有价值的,并且在实际的项目中能够进行的用户测试次数是有限的。通过真实的用户对每种草图都进行测试的设想代价过高,而这种方式的收获是非常有限的。 ### 使用档案进行草图设计 在进行API的草图设计时,使用[档案](http://tools.ietf.org/html/draft-amundsen-richardson-foster-alps-01)(profile)或[元语言](http://dublincore.org/documents/profile-guidelines/#sect-6)(meta language)是一种非常实用的方式。档案提供了一系列的概念,可用于草图的设计。一个优秀的档案可以类比为框与线,通过它创建系统图的多种草图。这些元素是设计师与评估者都能够理解的内容,它让快速地开发草图变得更简单。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4340e12949.png) 实际上,着手进行API草图设计过程有一种好方法,就是定义接口中最明显的单词列表。有哪些单词是用户必须知道的?哪些单词能够最好地表达你的目标受众的目的与任务?通过回答这些问题,并创建一份接口的词汇表,将有助于你形成对该接口的一种早期草图。 档案的美妙之处在于,它为我们提供了一种正规化的方式以共享及重用这种类型的信息。举例来说,我们在开始设计时可能会从某个[XML结构](http://www.w3.org/XML/Schema)文档中提取出单词、从[schema.org](http://schema.org/)获取一份词汇表、或者从某个[ALPS](http://tools.ietf.org/html/draft-amundsen-richardson-foster-alps-01)或[RDF](http://www.w3.org/RDF/)文档获取信息,这取决于我们的需求。 设计阶段的目标并非创建一份全面的词汇表,恰恰相反,早期的词汇表只是一个起点,我们可以从这一点开始绘制出其它类型的细节。我们可能会发现一个由20个左右的单词组成的列表就能够捕获接口的本质,这个列表就可以作为我们的起点。 这份词汇表为我们提供了一个基础,我们可以从它出发为API中的资源与关联设计草图,内容可以包括URI、资源名称、资源间的关联、链接文本以及其它结构化以及导航元素。请再次注意,没有必要画出草图的所有细节,我们的目标是表达出API里最重要的部分。 最重要的一点在于,最初的草图无需过于深入。比方说,请尽量避免在这一阶段就深入到错误流的建模,或响应消息元素的设计。这些部分可以稍后再加入,或者可以为它们进行专门的草图设计。 一份单独的草图无需反映出整个接口,实际上,为某些细节部分专门设计草图的方式可能更实用。举例来说,我们可以设计一个基本错误流的草图,它与整个API都具有相关性,或是设计一种响应消息格式的草图,这种格式可以应用到所有响应中。之后,在原型设计阶段,我们可以将这些思想应用到某个工作模型中。 ### 原型设计 在原型设计阶段,我们将有机会为接口设计一个具有更高保真度的模型,并且对草图设计阶段产生的一些假设进行验证。一个优秀的API原型应当是可以调用的,它应当能够处理真实的请求消息,并在必要时提供响应。开发者甚至应该能够通过使用这个原型API,创建出一个简单的应用。 不过,创建原型的成本应当低于一个完整的实现。有一种方法可以保持较低的成本,即模拟响应的消息,而不是由后台系统输出真实的响应消息。这种方式有时也称为接口的虚构(mocking),它是一种建立快速原型的好方法。 无论使用哪种方法建立原型,要点在于为投入找到一个合适的范围,能够支持后续的迭代。我们应当能够基于草图创建出两至三个不同的原形,并在过程中持续地学习。根据我们在原型设计阶段所学的内容,我们甚至可能会返回草图设计阶段,并尝试全新的方向。 通过原型,你的团队将有机会获得对于设计的早期用户反馈,并且能够对真实的使用情况进行观察。如果该接口的保真度已经达到了一定程度,你就可以让潜在的用户创建应用,并且对他们在实现阶段所面临的挑战进行观察。 负责实现的成员也应当加入原形评估过程中。一个经过良好设计的API不仅应当易于使用,同时还是可持续的、可靠的、高性能的、并且是历时长久的。虽然接口本身不应暴露数据模型的内部细节与服务器的架构,但负责实现者为告诉设计团队所做的决定提供一些参考建议,例如运行环境的限制,以及实现的成本。 设计周期好比一个科学工艺流程,而你应当抓住原型阶段的这次机会,在提出变更还为时未晚时对所做的假设进行验证。 ### 实现 实现者的任务是将一个原型化的接口转变成一种可以放心地进行实际应用的产品。交付一个安全的、可靠的、以及可伸缩的实现是一个很大的挑战,这一过程本身也需要经历一种专门的设计流程。 最后的原型以及支持性的草图描述了接口应该表现出的样子,它们反映出了所有的设计决策,并形成了一份规格,说明了具体需要创建什么样的产品。实际上,可以使用一种正式的接口描述语言(或称[IDL](http://en.wikipedia.org/wiki/Interface_description_language)),从原型阶段自然地过渡到实现阶段。 举例来说,如果你对原型API感到满意,就可以选择以一种[API Blueprint](https://apiblueprint.org/)文档(或[Swagger](http://swagger.io/)、[RAML](http://raml.org/)、[WADL](http://www.w3.org/Submission/wadl/),又或者是其它任何一种最适合你工作环境的格式)对其进行描述。 虽然这一阶段的目标是实现,但也不应停下设计的脚步。这一阶段是一个良机,让你通过真实的使用数据对整个设计过程中所做的假设进行进一步的验证。就像原型化的API允许我们观察使用情况一样,实现后的API允许我们在一个宏观层面对使用情况进行分析。 打个比方,你或许想对你之前所做的设计假设进行验证。应用程序的开发者是否真的在使用你为他们所创建的便利的操作?你是否吸引到你所期望的用户类型?新的用户是否在使用接口中的某些部分时遇到了麻烦? 经过分析,你可能会重新开始一次草图设计过程,以准备经过进一步改进的接口。 ## 通过工具实现过程的自动化 工具与技术的使用会极大地改进整个设计过程。那些能够降低草图与原型创建成本的工具能够让设计团队在更短的时间内创建更多的细节,使设计的决策得到改进。 对于多数设计过程来说,工具与自动化的引入是一个重要的部分。在建筑设计的世界中,[SHoP](http://www.shoparc.com/)(一个位于纽约的建筑师事务所)就通过创新、合作与基于工具的设计获得了成功。他们的流程中就引入了原型工具,让设计师能够体现出所用材料的物理特性。这种方法让他们得以创建数以千计的设计迭代,在每次迭代中都能够体现出易于评估的实现细节。 在API设计的世界中,这种基于工具的优化有很好的表现机会。实际上,在服务描述领域中,已经出现了一些卓越的Web API设计工具。 接口描述语言也能够提供支持性的工具,以简化编写描述的任务,这一点现在已经很常见了。这些编辑器工具能够缩短基于IDL的设计的创建时间,因此在更短的时间内创建更多的描述也变得更容易了。Swagger、RAML与Blueprint都提供了优秀的编辑工具以支持各自的语言。即使像WADL这样仅作为规范发布的IDL,也能够从[SoapUI](http://www.soapui.org/rest-testing/working-with-rest-services.html)这样的工具中受益。 [Apiary](https://apiary.io/)为Blueprint语言所提供的编辑器有很强的竞争力,因为它提供了一套完整的工作流工具以支持设计过程。只要以Blueprint编写一个简单的API描述,设计师就能够对文档进行评估、调用原型,甚至对调用过程进行分析。 **(****单击图片以放大****)** [![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f43412e484b.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f43412e484b.png) 不过,这些现有的工具中的大部分都只限于其所支持的描述语言。设计者必须理解IDL的语法,并且用这种语言设计界面。虽然这种设计风格能够吸引熟悉编程语言的使用者,但也会限制在早期的草图设计阶段很有价值的抽象与实验性的思考方式。 由于IDL及其对应工具的这些特征,它们很适用于原型设计过程,但对于草图设计的早期实验性活动来说实用性不高。 ## 使用可视化工具进行草图设计 人们对于使用可视化工具帮助他们进行API设计的兴趣正在不断升温。这些工具并非直接支持编辑IDL的行为,而是让设计者能够随意摆弄接口的一个可视化展现。 可视的建模工具提供了一种接口描述语言,这种语言多数是关于绘画的,或是基于图形的。虽然这个视角限制了接口展现的准确度,但它也让设计者能够在一个较高层次看到这个接口的全貌。这一点带来了进行改进的机会,而这种机会在手写的形式中往往并不明显。 易于使用的可视化编辑器也是进行自动化草图设计的良好选择,它综合了低保真度、抽象的展现以及可弃性等特征,这正是我们所需的。 我参与开发了一个名为[Rápido!](http://rapidodesigner.com/)的可视化建模工具,用于辅助API的草图设计。Rápido将用户限制在一个低保真度的细节中,这一点并非它的副作用,而是本身就是如此设计的。用户可以使用它进行档案、导航元素以及响应数据的建模,但不能用于设计逻辑流程或动态的响应。 当设计者开始创建一个新的Rápido项目时,他们需要为API设计一个词汇表。在得到一个初始的单词列表(或者从外部导入一个ALPS词汇表)之后,设计师就可以在一个超媒体画布中开始为API设计概念模型、创建资源、尝试URI名称甚至是链接的状态。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4341943fa7.png) 最终,设计者可以为草图中的每个资源或状态实现静态的响应消息,以增加保真度。最后,当草图设计阶段结束后,可以将整个设计导出成IDL格式,准备在原型阶段导入高保真度的工具。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4341a4919f.png) Rápido的目标是在Web API设计的领域中提供一种快速绘制的“鸡尾酒餐巾”式的草图的体验。如果你选择了适当的保真度,并且没有施加过于强烈的限制,那么它就能够成为API设计工具链中的重要一环。 ## 在迭代过程中取得成功 如果你按照本文中所描述的方式进行迭代式风格的设计,那么你将为团队带来一个设计高效API的良机。在过程的一开始创建多个低保真度的设计并进行评估,以培育实验能力与构思能力。然后创建高保真度的原型以及虚拟的实现,以评估早期的设计思想。最后,为真实用户实现整个设计,并获取数据以分析实际应用中的使用情况。 迭代式设计过程的特定细节取决于你的环境与项目,需要多少细节、多少次迭代、以及需要哪些评估技术,这些问题将留给设计者进行回答。但作为一种通用的经验法则,随着你的设计过程的推移,迭代的数量应当逐步减少,而在评估方面需要投入更多的精力。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4341c5594e.png) 优秀的API设计过程为你提供了一个创建最佳的接口的机会。但创建优秀API的秘密并不在于专家的指导或什么神秘的知识,而是一种通过优秀的工具、语言以及档案所优化的迭代流程的应用而实现的。使用这个公式所交付的API定能帮助你的组织获得成功。 ## 关于作者 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4341d43833.png) **Ronnie Mitra**是CA Technologies公司的API Academy部门的API设计总监。他多次帮助遍布全球的组织成功地完成了API的设计与实现。Ronnie具有超过30年的行业经验,在此期间内他不断地在失败中进行学习。 **查看英文原文:**[From Doodles to Delivery: An API Design Process](http://www.infoq.com/articles/doodles-to-delivery)
';

API描述、发现与档案入门

最后更新于:2022-04-01 03:13:16

> 原文出处:http://www.infoq.com/cn/articles/description-discovery-profiles-primer [TOC] ## Web API的下一阶段 虽然Web API的实现正变得越来越普及,但在工具方面还缺乏一些被广泛接受的标准,用以描述、发现,并且理解大量基于API的服务的意义。如何围绕着API的“元层面”对工具进行定义与实现,这方面仍然存在着大量的机会。 从目前来看,在以下三个领域方面,人们持续地表现出关注的态度以及开展实际的工作。这几个领域分别是: ### 描述 API描述指的是以一种让人类与机器都可读的形式对API进行描述,包括API的实现细节,例如资源与URL、表述格式(HTML、XML、JSON等等)、状态码以及输入参数。在这一领域方面,有几个关键的带头者正处于前沿的位置。 ### 发现 API发现是指按照一些特定的条件(例如上线时间、许可、定价以及性能限制),寻找以及选择能够提供所需服务(例如购物、用户管理等等)的Web API的过程。目前来说,这一过程主要还是由人类驱动的,但已经出现了一些工具,试图将这一过程中的某些部分实现自动化。 ### 档案 “档案”一直以来都是图书管理员与信息科学家所关注的内容,它定义了API请求与响应中所包含的词汇表术语的含义与使用方式。随着Web API的发展,档案也重新获得了技术人员的关注。虽然它依然是一种实验性质的思想,但有迹象显示,API的提供者与设计者正在开始实现对Web API档案的支持。 本文将对Web API元数据的这三个方面进行一次简单的回顾,并指出每个领域中的关键性工具与发展趋势。 ## 描述API的实现 目前,对于API的设计与实现的关注主要集中于它的描述格式。如今经常为人提及的格式包括[Swagger](http://swagger.io/)、[RAML](http://raml.org/)以及[API Blueprint](https://apiblueprint.org/),但其实现有的格式可以举出长长的一列。这些格式各自采取了一种略有不同的设计方式,但在本质上都提供了相同的基本特性:以多种不同级别的细节对Web API进行描述。 ### API优先 现如今,大多数设计方式都支持API优先的概念。你首先以某种基于XML、JSON或YAML的元语言描述你的API,并通过生成的文档(或文档集)自动生成一些实现方面的元素,例如服务端代码、人类可读的文档、测试harness、SDK,甚至是包含完整功能的API客户端。 API优先设计方式的一个例子是由[Apiary](https://apiary.io/)所推出的[API Blueprint](https://github.com/apiaryio/api-blueprint#api-blueprint)格式。它是一种基于[Markdown](http://daringfireball.net/projects/markdown/)的格式,目标是支持人类可读的API描述,同时又保证它的机器可读性。在以下示例中,你可以看到一个单一的资源(/message),它支持GET与PUT两种方法。你还可以看到其中对人类可读的文本的支持,以描述操作该API的方法。 **API Blueprint****描述示例** ~~~ FORMAT: 1A # Resource and Actions API This API example demonstrates how to define a resource with multiple actions. # /message This is our resource ## GET Here we define an action using the `GET` HTTP request method. As with every good action it should return a response + Response 200 (text/plain) Hello World! ## PUT OK, let's add an update action and send a response back confirming the posting was a success + Request (text/plain) All your base are belong to us. + Response 204 ~~~ [RAML](http://raml.org/)、[Swagger](http://swagger.io/)以及其它一些类似格式的工作方式也是大同小异。 在采用API优先方式时,你需要通过工具将设计时创建的元语言转换为可以在运行时起作用的东西。举例来说,Swagger的[codegen](https://github.com/swagger-api/swagger-codegen)工具能够解析描述文档,并生成相应的客户端代码。而[RAML-for-JAX-RS](https://github.com/mulesoft/raml-for-jax-rs)项目则在RAML描述与通过JAX-RS进行注解的Java代码之间提供双向转换的功能。 ### 代码优先 支持代码优先方式的描述模型为数极少,这种方式是通过源代码生成服务描述。不过,这一领域中最知名的格式 —— [Web Service描述语言](http://www.w3.org/TR/wsdl)(WSDL)在企业级应用社区中仍然相当流行,并且支持WSDL的工具为数众多,像微软的[Visual Studio](https://www.visualstudio.com/)与[Eclipse](https://eclipse.org/)等常见的编辑平台都提供了对它的支持。 下面是通过WSDL对某个简单的Web API进行描述的一个示例。 **HelloService WSDL****示例** ~~~ <definitions name="HelloService" targetNamespace="http://www.examples.com/wsdl/HelloService.wsdl" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <message name="SayHelloRequest"> <part name="firstName" type="xsd:string"/> </message> <message name="SayHelloResponse"> <part name="greeting" type="xsd:string"/> </message> <portType name="Hello_PortType"> <operation name="sayHello"> <input message="tns:SayHelloRequest"/> <output message="tns:SayHelloResponse"/> </operation> </portType> <binding name="Hello_Binding" type="tns:Hello_PortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="sayHello"> <soap:operation soapAction="sayHello"/> <input> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/> </output> </operation> </binding> <service name="Hello_Service"> <documentation>WSDL File for HelloService</documentation> <port binding="tns:Hello_Binding" name="Hello_Port"> <soap:address location="http://www.examples.com/SayHello/" /> </port> </service> </definitions> ~~~ 如果选择了代码优先方式,那么你就需要通过某些工具,将你的源代码转换为可重用的API描述元数据。Eclipse与Visual Studio都可以一键实现通过代码生成WSDL文件。另外还有一些工具能够读取WSDL文件,并生成各种实现元素。例如[SmartBear](http://smartbear.com/)的[SoapUI](http://www.soapui.org/soap-and-wsdl/working-with-wsdls.html)工具就能够基于WSDL文件生成代码、创建人类可读的文档,甚至是进行构建与运行测试集等任务。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f431cd98ffd.png) **图1\. SoapUI能够读取WSDL文件** ### 将API文档化 大多数API描述格式同样支持生成人类可读的文档,包括RAML、Apiary和 Swagger。实际上,开源的[Swagger-UI](https://github.com/swagger-api/swagger-ui)工具就是以文档生成器而闻名的(见下图),甚至让某些人产生了一种误解,认为Swagger仅仅是一种用于生成人类可读的API文档的工具。 ![document/2015-09-12/55f433863432c](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/document_2015-09-12_55f433863432c.png) **图**** 2. ****由****Swagger-UI****工具生成人类可读的文档** 有一些描述格式在设计时就专注于生成人类可读的文档,Mashery的[I/O Docs](http://www.mashery.com/product/io-docs)就是这方面的一个绝佳例子(见下图),它同时还提供测试方面的支持。 **Mashery****的I/O Docs****示例** ~~~ { "name": "Lower Case API", "description": "An example api.", "protocol": "rest", "basePath": "http://api.lowercase.sample.com", "publicPath": "/v1", "auth": { "key": { "param": "key" } }, "headers": { "Accept": "application/json", "Foo": "bar" }, "resources": { "Resource Group A": { "methods": { "MethodA1": { "name": "Method A1", "path": "/a1/grab", "httpMethod": "GET", "description": "Grabs information from the A1 data set.", "parameters": { "param1": { "type": "string", "required": true, "default": "", "description": "Description of the first parameter." } } }, "MethodA1User": { "name": "Method A1 User", "path": "/a1/grab/{userId}", "httpMethod": "GET", "description": "Grabs information from the A1 data set for a specific user", "parameters": { "param1": { "type": "string", "required": true, "default": "", "description": "Description of the first parameter." }, "userId": { "type": "string", "required": true, "default": "", "description": "The userId parameter that is in the URI." } } } } } } } ~~~ ### 描述与发现并非一回事 不过,无论你的专注点是通过元语言生成代码,或是由代码生成文档(或者其它任何一种方式),API描述只是整个创建与部署Web API流程中的一个环节而已。这一流程中还包括另一个重要环节,就是了解有哪些“现有”的API与服务,以及怎样使用它们。为了实现这一环节,你需要去发现这些API。 ## 发现现实世界中的API API发现是指定位某个能够完成特定任务所必须的Web API的能力。举例来说,你可能需要某个Web API,以实现在线购物、管理用户帐号或处理帮助平台上的请求的功能。在实际应用中,你应当能够以最小的代价发起一次搜索、找到符合你需求的API、获得访问该API的能力、实现对接代码并且开始使用该API。 可惜,现实情况总是有所差异的。 在讨论API发现时,我们通常所指的是应用程序编程接口(API)与一个实际 “运行中”的服务这两者之一。对于前一种情况来说,所讨论的内容只是一个接口,我们将用这个接口设计、实现以及部署属于自己的服务。而对后一种情况来说,我们所指的是某个现有的服务实例本身,你可以远程连接到这个服务中,并立即开始使用。由于这两种情况所面临的困难以及所产生的好处各不相同,因此应当通过示例进行一些考查。 ### API Commons 如果你所寻找的只是一种已经发布的API规范,并且能够自己完成它的实现,那么[API Commons](http://apicommons.org/)是一个很好的资源。API Commons的目的在于“为API规范、接口以及数据模型提供一种简单而透明的机制,让用户能够以协作的方式共享无版权归属的设计”。打个比方,如果你已经设计了一种API,并且乐于将它的设计分享给他人,让他们利用你设计的模型实现自己的服务,你就可以将自己的模型发布在API Commons上,并鼓励其他人使用。 另一方面,如果你打算实现某个API,而又想知道是否已经有人处理了相同的问题,那么你可以API Commons中进行一番搜索,看看有没有什么现成的设计可以使用。这种发布/订阅模式能够促使相似的服务重用相同的接口,而无需与参与者之间讨论协作的细节。在最理想的情况下,如果某个API调用者需要使用API Commons上所注册的某个API的设计,那么他也应当能够使用实现了相同设计的任何一种服务。 API Commons的运维模式得到了[Creative Commons](http://creativecommons.org/)的启发,目前由[Kin Lane与Steve Willmott](http://apicommons.org/contact.html)负责维护。 ### 可搜索的服务列表 在多数情况下,当人们谈及API发现时,他们所指的其实是发现某个能够利用的运行实例,即某个可用的服务。目前已经出现了一定数量的服务,它们将追踪实际的可用服务,并且大多数这种服务都是设计为人类可读的搜索引擎。其中最著名的一个例子就是Programming Web的[API目录](http://www.programmableweb.com/apis/directory)(见下图) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4320ba61b6.png) **图****3\. Programmable Web****的搜索界面** 当你的需求满足下表中的任意一条时,就可以考虑这种解决方案: * 搜索能够满足你的条件的服务 * 对于看起来能够满足你需求的API进行评估 * 参与该服务的接入过程,以及最后一条 * 编写你的API调用代码,以匹配你所选择的服务的API 你所选择的服务有可能会支持一种或多种我们已在上文中涵盖的API描述语言,这将简化你创建对应的API调用代码的工作。 这种发现服务有一个潜在的缺点,那就是并非所有的服务目录都经过了认真地审查(某些目录要依赖于“手动注册过程”)。你在这一过程中可能会找到一些有问题的API,它们或许不支持你所需的协议或格式,并且不再更新、或者无法满足你在性能与许可方面的需求,等等。此外,如果你打算使用多个第三方API,那么整个搜索、评估、接入以及接口生成循环可能会显得相当冗长。 ### 聚合服务 除此之外,还存在着另一种类型的API发现方式,即API聚合器。这些聚合器就如同一个或多个现有web service的某种代理,并提供一个单一的、统一的API,方便你进行编码。这方面的一个例子是Intel的[Mashery API Network](http://developer.mashery.com/)。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4320f72380.png) **图****4\. Mashery****的****API Network** 如果你计划调用多个第三方的Web API,那么聚合器能够让你在接入以及API整合方面所需付出的精力大大减少。聚合服务能够调用后端的API并进行正规化、管理你的访问密钥、某些服务甚至能够为你提供一个自定义的API,通过它简化在每个第三方API中共享关联数据的任务。 ### 可配置的运行时发现能力 人们还可以以另一种方式来看待这些API发现服务,即将其视为一种可配置的本地服务发现引擎。这种发现引擎只存在于某个公司的边界范围之内,并处理寻找以及连接到一或多个运行中的服务实例的工作,例如某个数据存储或业务组件。最近几年来,这种方式正在不断地发展中,这方面的例子包括[Apache Zookeeper](http://zookeeper.apache.org/)、HashiCorp的[Consul](https://www.consul.io/)、以及CoreOS的[etcd](https://coreos.com/etcd/)等等。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f43214a95b3.png) **图**** 5\. Apache Zookeeper****以及**** HashiCorp****的****Consul****提供了在企业内部进行运行时发现的功能。** 这种发现方式的一大优势在于,当你准备连接到组织内部的运行服务时,它提供了一个额外的间接层。你可以在运行代码中移除实际的服务地址与连接参数,并将这部分信息保存在配置文件中。某些服务甚至还允许你对于延迟与响应性进行一些限制,让它自动忽略或跳过运行时间较长的、或是不可用的服务实例,并连接至下一个可用的、健康的实例。 当然,这种抽象也存在着负面的因素。首先,由此产生的复杂性只有在大型服务中才值得一试。其次,对于这种服务的配置模型还没有实现标准化,这意味着你会最终对于某个提供商产生强依赖关系。最后,这种运行时的发现服务目前还无法用于组织之外的、公开的第三方服务。 ### 通过APIs.io与APIs.json实现Web规模的发现功能 与API的单一资源集合相对的是[APIs.io](http://apis.io/)的分布式搜索概念,APIs.io是由[3Scale](http://www.3scale.net/)与来自[API Evangelist](http://apievangelist.com/)的Kin Lane共同合作的成果。它是一种典型的搜索引擎,它本身并不负责托管API文档,而是跟踪互联网上找到的所有发现文件,并为这些文件中的数据提供一个搜索界面。 这些发现文件都是以一种名为[APIs.json](http://apisjson.org/)的格式所生成的。与API描述文档不同,APIs.json文件并不包含可用的URL、表述形式以及响应代码的详细信息,而是包含了指向这些描述文档位置的指针,以及指向服务条款、许可、联系方式以及其它相关数据的指针。 这一格式出现的时间很短,但它或许能够提供一种“粘合剂”,将API的描述与其它数据连接至一个单一的位置。由于这一格式也是机器可读的,因此它或许能够帮助搜索功能、甚至是Web API的上线细节实现自动化。 ### 描述与发现仍停留在细节层面 API描述与API发现的共同目标是简化构建与定位Web API的工作,但它们将大量的精力都专注于低层面的实现细节中,例如如何描述协议方法、返回代码以及响应的格式。对于编写实际代码来说,它们固然非常重要,但有时仍不足以实现设计优秀API的任务。由于它们的多数设计方式都专注于实现细节,因此往往只能描述某个运行中的服务的单一实例(或镜像集群)的特性。 如果你希望专注于更高层面的设计(例如用例、输入与输出),而不是充斥着协议、表述与资源的细节,那么你还需要别的工具。 ## 通过档案达成共识 在API元服务的开发中的一个最新趋势是创建与共享API档案信息的想法。与描述文档不同,档案文档提供了一个更高层次的视图,它描述了API所支持的功能,在有些情况下还能够描述客户端与服务器如何以一种机器可读的方式暴露它们的特性。 ### Web档案的历史简介 Web档案的出现已经有很长一段时间了,在1999年出现的[HTML 4.01](http://www.w3.org/TR/html4/cover.html)规范中就引入了档案这一属性。[元数据档案](http://www.w3.org/TR/html4/struct/global.html#h-7.4.4.3)可以定义为 a) 一个全局唯一的名称 (URI),或 b) 指向一个实际文档的链接(URL)。它的设计理念是让文档的作者得以为响应中的内容提供额外的描述性信息(例如文档的实用索引属性、服务条款等等)。 在2003年,[Tantek Çelik](http://tantek.com/)定义了[XHTML元数据档案](http://gmpg.org/xmdp/)(XMDP)。XMDP支持定义同时实现人类可读与机器可读的文档档案(是不是听上去有点熟悉?),这种文档实际上看起来与如今的API描述格式非常相像(参考以下示例)。 **XMDP****的一个示例** ~~~ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head><title>sample HTML profile</title></head> <body> <dl class="profile"> <dt id='author'>author</dt> <dd>A person who wrote (at least part of) the document.</dd> <dt id='keywords'>keywords</dt> <dd>A comma and/or space separated list of the keywords or keyphrases of the document.</dd> <dt id='copyright'>copyright</dt> <dd>The name (or names) of the copyright holder(s) for this document, and/or a complete statement of copyright.</dd> <dt id='date'>date</dt> <dd>The last updated date of the document, in ISO8601 date format.</dd> <dt id='identifier'>identifier</dt> <dd>The normative URI for the document.</dd> <dt id='rel'>rel</dt> <dd> <dl> <dt id='script'>script</dt> <dd>A reference to a client-side script. When used with the LINK element, the script is evaluated as the document loads and may modify the contents of the document dynamically.</dd> </dl> </dd> </dl> </body> </html> ~~~ 遗憾的是,档案属性没有得到广泛的应用,并且在HTML 5发布时从规范中被删除了,只能通过其它方式独立地[定义档案属性](http://dev.w3.org/html5/profiles/drafts/ED-html5-profiles-20100522/)。 在档案属性从HTML规范中移除之后,[Erik Wilde](http://dret.net/netdret/)提出了[RFC6906](https://tools.ietf.org/html/rfc6906)规范,定义了[Link Relation Value](http://www.iana.org/assignments/link-relations/link-relations.xhtml)这种档案,并注册在[互联网号码分配局](http://www.iana.org/)(IANA)中。Wilde的想法是将URI风格的档案进行标准化,通过一种不透明的标识符,“允许资源表述指定它们是否遵循了一种或多种档案”。 由于我们能够将响应的细节以档案的形式进行描述,因此人们开始不仅将档案应用于人类可读的文档,并且也应用在API的响应中。在最近几年中也出现了一些URL风格的档案实现。在本文中,我将介绍其中的两种:DCAP与ALPS。 ### 都柏林核心应用档案(DCAP) 在2009年,[都柏林核心元数据启动计划](http://dublincore.org/)(DCMI)发布了由他们设计的[DCAP](http://dublincore.org/documents/profile-guidelines/)格式,用于描述档案元数据。DCAP专注于支持资源描述框架(RDF)文档,它“定义了元数据记录,以此满足特定的应用程序需求。同时在全局定义词汇表与模型的基础上,提供了与其它应用程序在语义上互操作的能力。” 以下是DCAP文档的一个示例: **DCAP****文档示例** ~~~ Description template: Person id=person minimum = 0; maximum = unlimited Statement template: givenName Property: http://xmlns.com/foaf/0.1/givenname minimum = 0; maximum = 1 Type of Value = "literal" Statement template: familyName Property: http://xmlns.com/foaf/0.1/family_name minimum = 0; maximum = 1 Type of Value = "literal" Statement template: email Property: http://xmlns.com/foaf/0.1/mbox minimum = 0; maximum = unlimited Type of Value = "non-literal" value URI = mandatory ~~~ 创建DCAP的原因是因为如今的表述格式(RDF)非常受限,并且过于泛用(例如元组),在这种情况下,DCAP能够改进共享数据语义的能力。DCAP的一个关键优势在于,它并不是直接指出在响应中使用了哪些术语(例如givenName、familyName、customer、user等等),而是指出这些术语是如何进行通信的。这种方式为创建可共享的在线词汇表铺平了道路。 目前已经出现了一部分与DCAP相关的工具,包括在线编辑器、验证功能以及HTML的生成器。但DCAP的使用主要限制于图书馆、信息科学与学术社区等领域,很少看到将DCAP用于业务相关的Web API中。 ### 应用级别的档案语义(ALPS) 在2013年,Leonard Richardson、Mark Foster与我共同发布了[ALPS互联网草案](http://tools.ietf.org/html/draft-amundsen-richardson-foster-alps-01)的第一个版本。与DCAP类似,ALPS同样借用了XDMP的思想,它为数据元素(例如userName、userStatus等等)与用例元素(例如find-user等等)都提供了元数据。 以下是通过一个ALPS文档描述一个简单的搜索API的示例: **由ALPS****文档所描述的搜索API** ~~~ { "alps" : { "version" : "1.0", "doc" : { "href" : "http://example.org/samples/full/doc.html" }, "descriptor" : [ { "id" : "find-user", "type" : "safe", "doc" : {"value" : "User search form" }, "descriptor" : [ { "id" : "userName", "type" : "descriptor", "doc" : { "value" : "input for search" } }, { "href" : "#userStatus" } ] }, { "id" : "userStatus", "type" : "descriptor", "description" : {"value" : "results filter"}, "ext" : [ { "href" : "http://alps.io/ext/range", "value" : "active,inactive" } ] } ] } } ~~~ ALPS文档专注于接口层面的互动,按[Eric Evans](https://twitter.com/ericevans0)的话来说也就是[边界上下文](http://martinfowler.com/bliki/BoundedContext.html)。ALPS并不会处理一些实现方面的细节,例如协议(HTTP、XMPP等等)、格式(HTML、JSON等等)甚至是资源的URL。由于它无需关注实现细节,因此ALPS文档能够作为API设计工具的原始资料,以生成人类可读的文档,甚至可作为发现过程中的一个环节,帮助你选择一个合用的API。 目前,对于ALPS最佳的描述是将其视为一个“不稳定的”规范,并且在网上关于如何使用它的示例也非常罕见。[Ronnie Mitra](https://twitter.com/mitraman)设计了一个实验性质的[Rapido API设计器](https://github.com/apiacademy/rapido-spa)(见下图)能够使用ALPS文档作为输入,而[Pivotal](http://pivotal.io/)的[Spring-Data](http://docs.spring.io/spring-data/rest/docs/current/reference/html/#metadata)工具能够将ALPS文档的生成作为API构建过程中的一环。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4321901c89.png) **图**** 6. ****通过****Rapido API****设计器管理档案的词汇表** ### 只是一种尝试,还是将领导新的潮流? 虽然在Web API中使用档案的做法重新吸引了人们的注意,但这种技术到底是一种会逐渐消失的实验?还是会由此开创一个新的趋势,以专注于独立地定义Web API的数据与行为语义?现在下判断还为时过早。 ## 所面临的挑战 在本文中,你对于Web API元数据的三个关键领域,即描述、发现及档案有了一个初步的了解。Swagger、RAML以及Apiary等技术目前掌握着主动权,它们控制了API描述这一领域,而在这个发展良好的生态系统中还存在着一些其它技术。有一些工具能够通过描述格式实现代码与文档生成的自动化,并且围绕着几个关键的格式,出现了许多功能强大的工具集。 API发现这一领域依然由以人类驱动的搜索与选择方式作为主导,而像Intel的Mashery这种关键的API聚合器依然是通过提供一种聚合的方式订阅远程的API。而自动化的、基于配置的定位服务也正在逐渐兴起,以支持连接到企业级服务实例的功能。其中有部分方式或许将提供对基于互联网的API进行自动化服务发现的功能。 最后是API档案,它常用于图书馆与信息科学领域中,而它在与业务相关的Web API领域中也逐渐引起了人们的关注。目前出现的一些首创概念要么还属于实验性质,要么很少为人所知,但已经开始有一些API提供商开始支持API档案了。 Web是一个充满活力的、飞速发展的领域,为了即时到来的时刻,不妨关注一下API生态系统中的这种“元层面”的思想,这一过程应当是充满趣味的。 ## 关于作者 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-12_55f4321a6daff.jpg) **Mike Amundsen**是一位国际知名作者与讲师,他经常在全球各地旅行,就分布式网络架构、Web应用开发以及其它主题进行顾问工作与演讲。Amundsen在API Academy担任架构总监的角色,负责为全球范围内的公司提供服务,帮助客户与企业了解如何最好地利用由API带来的无数机遇。在过去15年间,Amundsen编写了大量与编程相关的书籍与论文。他目前正在撰写一本名为《学习客户端超媒体》的新书,其中涵盖了构建能够充分利用超媒体API服务的客户端应用的常见方式。他最近出版的一本书是与Leonard Richardson合著的《RESTful Web APIs》,于2013年出版。Amundsen在2011年出版的书籍《通过HTML5与Node创建超媒体API》是在构建具有可适应性的Web应用时经常被引用的一本著作。他目前正在为O’Reilly创作一本新书《学习客户端超媒体》,在2015年秋季应当能够看到它的身影。 **查看英文原文:**[Description, Discovery, and Profiles: A Primer](http://www.infoq.com/articles/description-discovery-profiles-primer)
';

前言

最后更新于:2022-04-01 03:13:14

本系列文章专注于Web API之 “元语言”的三个关键领域:即API描述、API发现以及API档案。这些文章将涵盖所有这三个重要的趋势,并包括对这一快速发展的领域的一些关键人物的专访。 > 来自InfoQ的这篇文章是“[描述、发现以及档案:进入Web API的下一阶段](http://www.infoq.com/articles/description-discovery-profiles-series-intro)”系列文章中的一篇,你可以在这里进行[订阅](http://www.infoq.com/feed/apis-description-discovery-profiles),以便通过RSS获取新文章的通知。
';