良好行为REST风格的客户端交互(Well-behaving RESTful Client Inte

2019-09-22 02:45发布

我有什么似乎是有关实现严格符合REST架构原理的数据访问客户端一个相当简单的问题。 首先,让我们假设我有一个良好的表现REST API,我想用一个Django应用程序使用。 我会发现什么服务(编辑跟进)开始:

GET example.com/services/ HTTP/1.1

HTTP/1.1 200 OK
<?xml version="1.0" encoding="UTF-8"?>
<services>
  <service>
    <name>Widgets</name>
    <link>http://example.com/services/widgets/</link>
    <item_link>http://example.com/services/widgets/{widget_id}/</item_link>
  </service>
  <service>
    <name>Factories</name>
    <link>http://example.com/services/factories/</link>
    <item_link>http://example.com/services/factories/{factory_id}/</item_link>
  </service>
  ...
</services>

现在,因为我建立根据各地消费这个API Django应用程序,我将如何继续保持REST风格探索这些服务? 要坚持REST原则,我的应用程序必须通过接收到的超媒体驱动。 我想第一步是很容易的 - 通过给定名称的服务进行交互。 我设置了一个Django观点如下:

def get_service(request, service_name):
    doc = etree.parse(urllib.urlopen('http://example.com/services/'))
    uri = doc.xpath("service/name[.='%s']/following-sibling::*" % service_name)[0].text
    ...

从中我会执行另一项请求(编辑跟进):

GET example.com/services/widgets/ HTTP/1.1

HTTP/1.1 200 OK
<?xml version="1.0" encoding="UTF-8"?>
<widgets>
  <item_link>http://example.com/services/widgets/{widget_id}/</item_link>
  <widget>
    <id>1</id>
    <name>Whizbang Foobar</name>
    <link>http://example.com/services/widgets/1</link>
  </widget>
  ...
</widgets>

现在,我将显示在渲染的Django模板部件的简单列表。 从这里,虽然,我该如何继续使用此服务REST风格交互? 也许,我迷迷糊糊地扑进混乱,但唯一合理的事情,我能想出正在实施的应用视图的众多量或薄Django的数据模型,以坚持服务URI。

我最关心的归结为,这是微不足道的,而不严格遵守REST架构准则的事,但我觉得我已经错过了船完全试图这样做。 我理解正确设计的REST API和客户端不“易”,但似乎我迫切需要一个类似的例子,通过实际执行工作。

我对这个问题的长度和冗长和干瘪的读者必然facepalming道歉。

跟进:

在下面的实现这些交互的有效方式(使用URI模板)? 出于演示的目的(代替一个更抽象的实现),另一个Django的视图来检索资源集合项目:

def get_item(request, service_name, item_id):
    doc = etree.parse(urllib.urlopen('http://example.com/services/'))
    uri = doc.xpath("service/name[.='%s']/following-sibling::item_link" % service_name)[0].text
    ...

然后后续请求:

GET example.com/services/widgets/1 HTTP/1.1

HTTP/1.1 200 OK
<?xml version="1.0" encoding="UTF-8"?>
<widget>
  <id>1</id>
  <name>Whizbang Foobar</name>
  <tags>foo bar baz ham eggs</tags>
  <index_link>http://example.com/services/widgets/</index_link>
</widget>

Answer 1:

我最关心的归结为,这是微不足道的,而不严格遵守REST架构准则的事,但我觉得我已经错过了船完全试图这样做。 我理解正确设计的REST API和客户端不“易”,但似乎我迫切需要一个类似的例子,通过实际执行工作。

我已经能够找到的最好的例子是Sun云API 。 大多数的文件描述了系统,这似乎是关键拉动这种事情离所使用的各种媒体类型。

我发现它在帮助你开发你的API同时在写你的客户。 这样,你能发现什么是可能使你的API苦为马上进行编码并解决问题。

这是不容易的。 如果按照HATEOAS限制着它的逻辑结论,每个媒体类型定义将由家庭用户中的一个来处理。 为了可以让所有的资源都遵循的行为类似的模式在某种程度上,你写的客户的工作将变得更加容易。

例如,你可以定义一个媒体类型“索引”,仅仅列出了相关的资源。 指标定义分页链接,让项目在列表中,用域名等项目

然后,你可以定义一个名为“项”基础介质类型。 项目有一个链接以显示它的父目录,更新/删除自身,等你的资源的Widget然后可以通过两种不同的媒体类型来表示 - 一个指数和一个基于项目。

你可以通过实现处理索引媒体类型的单一类开始。 然后,你可以编写处理所有常见项目的媒体类型行为的基类。 最后,你可以写一个小窗口客户端处理所有特定小部件的行为,它扩展了项目的客户端。 这些客户可能使它们的功能在他们编写语言的惯用方式(多链接和数据字段的可用性)。

然后处理从服务器的响应是匹配的回应你写一个客户的MIME类型的问题。

换句话说,即使为您服务为一体的客户端将进行范围有限,许多客户了,他们将各自基于共同的行为,因此可以在干燥的方式来实现。



Answer 2:

从我的经验REST模型使得如果陈述和它们所包含的链接直接转换到客户端UI更有意义。 在这种情况下它是指导REST接口的浏览用户。

我经常看到有人试图使用REST接口作为一种基于HTTP的数据访问层。 有了这个心理模型,超链接数据提供了比结构数据的关系而已。 它变得难以建立在该接口之上的应用程序行为不违反REST风格的约束。

我喜欢把一个RESTful接口作为提供UI内容是要渲染一些任意的技术内容的应用程序。 不幸的是,剩下的就是频繁相比,网络服务,在我看来,适合在不同的建筑层。 Web服务提供的数据是由客户端应用程序进行处理。 REST风格的接口应提供将要呈现给用户的内容。

当然你可以使用REST接口将数据传送到远程应用程序,但认为它是简化屏幕抓取。

当写REST接口,客户端我觉得它有用想象,我写一个自定义的Web浏览器,只能识别由RESTful接口交付,是媒体类型的硬编码在特定的URL开始并没有地址栏!



Answer 3:

Sun云API文档是一个RESTful API的一个很好的例子,专注于媒体类型。



Answer 4:

如果我没有理解你的问题,你想探索未知的服务,是否正确?

如果是这样,那么你可以,例如继续与OPTIONS请求的“小部件”的资源,看看它支持的HTTP方法(这些都应该在上市Allow的响应头)。
然后,您可以做同样为中找到的所有的URI <link rel="whatever">元素。 如果资源发现这种方式表明它支持GET ,然后把它拿来和重复...
这样,你应该能够探讨所有嵌套的资源。

这种探索当然会只让你这么远,因为真正与服务交互 ,你需要知道它的媒体类型(或表示),有什么不同的<link rel="whatever">您发现行动实际上的意思。 这一步无法实现自动化,你必须阅读有关服务的文档,并建立相应的客户端你。 我建议您阅读文章“ 如何获得一杯咖啡 ”,我想解释这种互动非常好。



文章来源: Well-behaving RESTful Client Interactions
标签: django rest