简体   繁体   English

RESTful Web服务:尝试使用自定义XML实现HATEOAS

[英]RESTful web services: trying to achieve HATEOAS with custom XML

I am working on an enterprise system that will utilise a RESTful web service between mobile clients and a central server. 我正在开发一个企业系统,它将在移动客户端和中央服务器之间使用RESTful Web服务。 As RESTful as possible, let's say. 尽可能使用RESTful,让我们说。

My question relates to HATEOAS (hypermedia as the engine of application state), and the use of custom xml in HTTP response bodies. 我的问题涉及HATEOAS(超媒体作为应用程序状态的引擎),以及在HTTP响应主体中使用自定义xml。

This system will never ever be used by public clients, but I like the HATEOAS idea of being able to modify the server-side resource allocation pattern later without having to reconfigure each of the clients independently. 该系统永远不会被公共客户端使用,但我喜欢HATEOAS的想法,即能够在以后修改服务器端资源分配模式,而无需独立地重新配置每个客户端。 If we decide that due to scaling issues we need to spread the server function over multiple physical boxes, no problem, this will be reflected in the URIs that are generated when a client (or the server under instruction from a client) creates a new resource. 如果我们决定由于扩展问题我们需要在多个物理盒上扩展服务器功能,没问题,这将反映在客户端(或来自客户端的指令下的服务器)创建新资源时生成的URI中。

Our business domain is highly specific and unusual. 我们的业务领域非常具体和不寻常。 As such, I would like to use custom XML for HTTP response entity bodies throughout the web service, and the client will parse resource URIs out of the xml in order to stay informed of resource locations that it can use when modifying its own application state. 因此,我想在整个Web服务中为HTTP响应实体主体使用自定义XML,并且客户端将从xml中解析资源URI,以便随时了解它在修改自己的应用程序状态时可以使用的资源位置。 I know that this 'breaks' the H part of HATEAOS. 我知道这会“打破”HATEAOS的H部分。

eg when a client POSTs a transaction to the server for processing, the server might include the following xml fragment in the 201 HTTP response body (as part of a larger xml document). 例如,当客户端将事务发送到服务器进行处理时,服务器可能在201 HTTP响应主体中包含以下xml片段(作为更大的xml文档的一部分)。 The server would also inform the client of the URI for the newly created transaction resource itself, but this would probably only be included in the Location HTTP header. 服务器还会通知客户端新创建的事务资源本身的URI,但这可能只包含在Location HTTP头中。

<resulturi>http://resultserver/results/1234.xml</resulturi>

Is this so bad? 糟糕吗? There is very little chance that the clients using this service will ever be browser based. 使用此服务的客户端几乎不可能基于浏览器。 What are the other advantages of hypermedia over delivering the uris as plain text within xml? 超媒体在xml中以纯文本形式提供uris的其他优点是什么?

I guess I could go to XHTML, but the parser on our mobile platform is much more efficient with POX. 我想我可以去XHTML,但我们的移动平台上的解析器使用POX更有效率。

What you are doing by returning an url in resulturi is effectively hypermedia already. 你在resulturi中返回url所做的事实上已经是超媒体了。 The only problem is that you need a media-type that tells the client how the response is formatted so that it can parse the urls out in a predictable and documented way. 唯一的问题是,您需要一种媒体类型,告诉客户端如何格式化响应,以便它可以以可预测和记录的方式解析URL。

Option 1: Create your own media type like vnd.yourcompany.Resource+xml. 选项1:创建自己的媒体类型,如vnd.yourcompany.Resource + xml。 By doing this you are stating that the media type can be parsed by an xml parser, but it follows some special rules that are defined by your company. 通过执行此操作,您将声明媒体类型可以由xml解析器解析,但它遵循由您的公司定义的一些特殊规则。 At this point you can use whatever standard you want for defining hypermedia links (see this question). 此时,您可以使用任何标准来定义超媒体链接(请参阅问题)。 One nice advantage of this is that if in 6 months you decide you need to make a breaking change to the format of your XML you can create a vnd.yourcompany.ResourceV2+xml and as long as you were smart enough to use the accept-header on your old clients, you can smoothly introduce the new format side by side with the old one by making new client applications accept the new format. 这样做的一个很好的优点是,如果在6个月内您决定需要对XML的格式进行重大更改,您可以创建一个vnd.yourcompany.ResourceV2 + xml,只要您足够聪明以使用接受 - 在您的旧客户端上,您可以通过使新的客户端应用程序接受新格式,顺利地将新格式与旧格式并行引入。

Option 2: I'm only half serious about this option, but I have considered pushing for a new mediatype called application/hyperxml+xml. 选项2:我对这个选项只有一半认真,但我考虑过推动一种名为application / hyperxml + xml的新的mediatype。 The document would follow the same rules as application/xml but would also make use of XLink for hypermedia. 该文档将遵循与application / xml相同的规则,但也会使用XLink进行超媒体。 This would allow people who are using javascript to parse the XML document to also take advantage of hypermedia in a standardized way. 这将允许使用javascript解析XML文档的人也以标准化方式利用超媒体。

Option 3: Use XHtml. 选项3:使用XHtml。 I don't understand why your parser has problems with Xhtml, but I'll take your word for it. 我不明白为什么你的解析器有Xhtml的问题,但我会接受你的话。

There are two important pieces of information your RESTful server will need to process requests, regardless of the underlying markup language: a media type and a URI. 无论底层标记语言如何,RESTful服务器处理请求都需要两条重要的信息:媒体类型和URI。 Assuming a media type for a given URI would introduce client-server coupling. 假设给定URI的媒体类型将引入客户端 - 服务器耦合。 It would, for example, prevent the same URI from ever serving two different kinds of media type. 例如,它会阻止相同的URI提供两种不同类型的媒体类型。

XML isn't the only option when designing hypermedia formats. 在设计超媒体格式时,XML不是唯一的选择。 Check out the Sun Cloud API , which defines a hypertext-driven REST API based on JSON (although it appears to not use media type with its hyperlinks). 查看Sun Cloud API ,它定义了基于JSON的超文本驱动的 REST API(尽管它似乎没有使用带有超链接的媒体类型)。 It's not difficult to go from this approach to one that combines media types with hyperlinks. 从这种方法转变为将媒体类型与超链接相结合的方法并不困难。

For example, you could define a JSON data structure called Link that looks like this; 例如,您可以定义一个名为Link的JSON数据结构,如下所示;

{
  "name":"human-readable label for link",
  "uri":"http://example.com/resources/123",
  "media_type":"application/vnd.com.example.Resource+json"
}

Hypermedia does not require HTML or even fully qualified URIs for that matter. Hypermedia不需要HTML甚至完全限定的URI。 If your media type defines a rule for turning some elements of the response into de-referenceable resources then you have hypermedia. 如果您的媒体类型定义了将响应的某些元素转换为可引用资源的规则,那么您就拥有了超媒体。

<result>1234</result>

The above example, combined with a media type rule on how to dereference the contents of the result element is hypermedia in the same way that: 以上示例结合关于如何取消引用结果元素内容的媒体类型规则是超媒体,其方式与:

<result>/foo/1234</result>

is with a rule to prepend the base http URI. 有一个规则来预先添加基本http URI。 So is the example below where the fact that the http string is dereferencable may be left implicit. 下面是一个示例,其中http字符串是可解除引用的事实可能是隐含的。

<result>http://myserver.com/foo/1234</result>

However, while they are all hypermedia and meet that constraint, I would argue against creating your own new hypermedia production rules and tags if at all possible and just re-use existing ones. 然而,虽然它们都是超媒体并且满足了这种约束,但我会反对创建自己的新超媒体制作规则和标签,如果可能的话,只需重新使用现有规则和标签。 The first example makes it less obvious to the user that this element represents a hyperlinked resource than the last example. 第一个示例使用户不太明白此元素表示超过上一个示例的超链接资源。

I would suggest that rather than hand code these hyperlinks, use a tool which creates those hyperlink for you. 我建议不要手动编码这些超链接,而是使用为您创建这些超链接的工具。 Interaction oriented programming is a good method to create these interactions (hyperlinks). 面向交互的编程是创建这些交互(超链接)的好方法。 Please follow this link this technology worked for us http://www.masterkube.com/hateoas_technology.html 请关注此链接,此技术适用于我们http://www.masterkube.com/hateoas_technology.html

At a very minimum (even if you do nothing else), you should put your URL in an XLink attribute instead of the element content: 至少(即使你什么也不做),你应该把你的URL放在XLink属性而不是元素内容中:

<resulturi xlink:href="http://resultserver/results/1234.xml"/>

XML processors are able to parse and follow these as URIs natively. XML处理器能够本地解析和跟踪这些URI作为URI。 As a general rule, text which is not translatable or could never have sub-elements should be in an attribute to enforce such restrictions. 作为一般规则,不可翻译或永远不能具有子元素的文本应该属于强制执行此类限制的属性。

But beyond this, do what others have suggested and define your media type so that the meaning can be understood by clients. 但除此之外,做其他人的建议并定义您的媒体类型,以便客户可以理解其含义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM