关于2008年Fielding的一篇博文《REST APIs must be hypertext-driven》的一些思考

来源:互联网 发布:淘宝天刀代购 编辑:程序博客网 时间:2024/05/16 01:46

Fielding的博客原文在:http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

What needs to be done to make the REST architectural style clear on the notion that hypertext is a constraint? In other words, if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period. Is there some broken manual somewhere that needs to be fixed?

Fielding指出REST架构中的应用程序的状态转化应该是由超文本驱动的。

在文中提及了REST API的若干原则:

1.      A REST API should not be dependent on any single communication protocol, though its successful mapping to a given protocol may be dependent on the availability of metadata, choice of methods, etc. In general, any protocol element that uses a URI for identification must allow any URI scheme to be used for the sake of that identification. [Failure here implies that identification is not separated from interaction.]

关于这一点我并不是特别理解,但是根据最后方框里的话大概推测出他的观点应该是对资源的标记应该从交互的定义中分离出来,即是说所采用的资源标记方式应该独立于特定的通信协议。

2.      A REST API should not contain any changes to the communication protocols aside from filling-out or fixing the details of underspecified bits of standard protocols, such as HTTP’s PATCH method or Link header field. Workarounds for broken implementations (such as those browsers stupid enough to believe that HTML defines HTTP’s method set) should be defined separately, or at least in appendices, with an expectation that the workaround will eventually be obsolete. [Failure here implies that the resource interfaces are object-specific, not generic.]

这一点指出REST API不应采用通信协议中还未确定或可能改变的方法。

3.      A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. Any effort spent describing what methods to use on what URIs of interest should be entirely defined within the scope of the processing rules for a media type (and, in most cases, already defined by existing media types). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]

这一点击中了现有很多REST API,根据一些初步的观察,我发现大多数的REST API都是使用额外的信息(out-of-band)来定义和描述交互,而实际上这是不必要的,因为交互方式在媒体类型(media type,例如HTML文件)的处理规则中已经被定义好了。根据上面Fielding的话来看,API的描述应主要集中在资源的表示representing)、驱动(driving)应用程序状态转换定义资源的关系relation)上。

4.      A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace. Instead, allow servers to instruct clients on how to construct appropriate URIs, such as is done in HTML forms and URI templates, by defining those instructions within media types and link relations.[Failure here implies that clients are assuming a resource structure due to out-of band information, such as a domain-specific standard, which is the data-oriented equivalent to RPC's functional coupling].

这一点说的是REST API应当引导用户/客户端构造满足要求的URI,而不是向用户提供一个固定的URI

我找到了两个对比鲜明的例子来说明这个观点。

反面例子是人人网开放平台的REST APIhttp://wiki.dev.renren.com/wiki/API),给定了一个固定的URI,所有的调用都通过POST来完成,这实际上就是包裹着REST外衣的RPC架构;

正面的例子是:Google Maps APIhttps://developers.google.com/maps/?hl=zh-cn)。

首先它给出了一个合法URI的格式,例如http://maps.googleapis.com/maps/api/directions/output?parameters,其中http://maps.googleapis.com/maps/api/directions/的部分映射到所调用的资源,是固定不变的。之后的output指代返回的数据格式,用jsonxml来代替;而问号之后的parameters则由用户自行确定,在API说明文档中有详细的参数描述和示例。

5.      A REST API should never have “typed” resources that are significant to the client. Specification authors may use resource types for describing server implementation behind the interface, but those types must be irrelevant and invisible to the client. The only types that are significant to a client are the current representation’s media type and standardized relation names. [ditto]

这一点说的大体是REST API不应描述资源的类型,而应该描述资源的具体表现(representation)的媒体类型和标准化的关系名称。

6.      A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API). From that point on, all application state transitions must be driven by client selection of server-provided choices that are present in the received representations or implied by the user’s manipulation of those representations. The transitions may be determined (or limited by) the client’s knowledge of media types and resource communication mechanisms, both of which may be improved on-the-fly (e.g., code-on-demand). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]

这一点想要表达的是对REST API的访问应该可以完全由URI和标准化的媒体类型集合完成。用户只需要从URI中明确资源的语义,即该资源满足自己的要求,同时具备处理媒体类型的能力,就能够顺利访问API,而不需要任何额外的知识。文中的out-of-band information应该指的是WSDL等交互描述文档所携带的信息。

总结:跟读Fielding的博士论文时很相似,我又再次陷入了同样的思维误区当中,上文Fielding所指的REST API是一种广义上的API,例如所有的网页网址都可以包含在FieldingREST API的定义中,而且他一直阐述的大部分Client调用API的过程,都是在浏览器中完成的,对于机器调用API则只是简单略过。假如把RESTful Web Service的思想完全套用在Fielding的陈述中,将陷入似是而非的思维迷宫当中。

反思:我发现我过度纠结在Web Service的自动化处理当中,而实际上所有的Client都是在良好地对API进行封装的情形下由人在主导交互的进行。Fielding所提出的REST API应由超文本来进行驱动的观点印证了我的想法,因为超文本目前还仅仅是人类可读的。

原创粉丝点击