【问题标题】:Can you help clarify some points regarding RESTful services and Code Generation?你能帮助澄清一些关于 RESTful 服务和代码生成的观点吗?
【发布时间】:2011-03-02 22:57:56
【问题描述】:

我一直在努力理解我一直在阅读的关于 RESTful 服务的几点。我希望有人可以帮助澄清。

1a) 在谈论 RESTful 服务时,似乎普遍厌恶生成的代码。

1b) 如果您使用 WADL 为 RESTful 服务生成客户端,那么当服务更改时,您的客户端代码也会发生更改。

为什么我不明白:无论您是在引用 WADL 并使用生成的代码,还是手动从 RESTful 响应中提取数据并将它们映射到您的 UI(或您正在对它们执行的任何操作)(如果发生变化)在底层服务中,代码似乎在这两种情况下都会中断。例如,如果返回的数据从 FirstName 和 LastName 更改为 FullName,则在这两种情况下,您都必须更新代码以获取新字段并可能以不同方式处理它。

2) RESTful 服务不需要 WADL 的论点,因为返回类型应该是众所周知的 MIME 类型,并且您应该已经知道如何处理它们。

为什么我不明白:是否期望服务返回的每种“类型”数据都会存在唯一的 MIME 类型?如果是这样,是否意味着 RESTful 服务的消费者需要阅读 RFC 来确定返回数据的结构、如何使用每个字段等?

我读了很多书试图自己弄清楚这一点,所以我希望有人能提供具体的例子和现实世界的场景。

【问题讨论】:

  • 这篇文章很好地总结了我的问题,但从另一个角度来看,我认为它解释得不够好,所以我真的试图澄清本文的要点文章:bitworking.org/news/193/Do-we-need-WADL

标签: web-services rest code-generation


【解决方案1】:

REST 可能非常微妙。我也读了很多书,每隔一段时间我就会回去阅读Chapter 5 of Fielding's dissertation,每次都能找到更多的见解。第一次时它像泥巴一样清晰(尽管有些事情是有道理的),但只有在我尝试应用这些原则并使用构建块时才变得更好。

所以,根据我目前的理解,让我们试一试吧:

为什么 RESTafarian 不喜欢代码生成?

简短的回答:如果您使用超媒体(+链接)没有必要

上下文:显式定义客户端和服务器之间的合约 (WADL) 不会减少耦合足够:如果您更改服务器,客户端会中断,您需要重新生成代码。 (恕我直言,甚至自动化它只是底层耦合问题的一个补丁)。

REST 帮助您在不同级别上解耦。 超媒体可发现性是最重要的产品之一。另见相关概念HATEOAS

我们让客户“发现”可以从我们操作的资源中做什么,而不是之前定义合同。我们加载资源,检查“命名链接”,然后点击这些链接或填写表格(或表格链接)以更新资源。服务器通过它基于状态提出的选项充当客户端的指南。 (想想业务流程/工作流/行为)。如果我们使用合同,我们需要知道这个“带外”信息并在更改时更新合同。

如果我们使用带有链接的超媒体,则不需要“单独的合同”。一切都包含在超媒体中——为什么要设计一个单独的文档?甚至 URI 模板也是带外信息,但如果保持简单,则可以像 Amazon S3 一样工作。

是的,在传输表示(超媒体)时,我们仍然需要一个共同立场,因此我们定义您自己的媒体类型或使用广泛接受的媒体类型,例如 Atom 或Micro-formats。因此,在基本构建块(链接 + 表单 + 数据 - 超媒体)的约束下,我们通过将带外信息保持在最低限度来减少耦合。

首先,超媒体似乎不会改变变化的影响:):但是,存在细微的差异。一方面,如果我有 WADL,我需要更新另一个文档并部署/分发。使用纯超媒体没有影响,因为它是嵌入式的。 (想象一下通过复杂的系统交织产生的变化)。根据您的示例,拥有 FirstName + LastName 并添加 FullName 并不会真正影响客户端,但删除 First+Last 并替换为 FullName 甚至在超媒体中也是如此。

附带说明:REST 统一接口(动词约束 - GET、PUT、POST、DELETE + 其他动词)将实现与服务分离。

也许我完全错了,但另一种可能性可能是代码生成的“心理反击”:WADL 让人想到“传统 Web 服务 (WSDL+SOAP)”/RPC 中的 WSDL(合同)部分反对 REST。在 REST 中,状态是通过超媒体而不是 RPC 传输的,RPC 是用于更新服务器状态的方法调用。

免责声明:我没有详细完成所引用的文章,但我确实给出了一些重要的观点。

【讨论】:

  • 感谢您的回答。感谢您花时间尝试解释。虽然对于机器对机器的通信以及 REST 在这方面如何优于 SOAP 对我来说仍然很模糊,但我确实理解使用已知 MIME 类型的好处,以及在某些情况下使用 REST 优于 SOAP 的好处。我相信您的回答可以更好地尝试回答我的问题,因此我将奖励您。虽然我仍然觉得完整的画面还没有画出来,对我来说。谢谢。
  • REST(ful) 服务是否通常具有“索引”页面——很像网站的默认页面?人们说客户端不需要知道如何构造 URL,因为客户端只是跟随 REST 响应中的链接。那么客户端如何执行第一个请求呢?
  • 您的服务需要一个入口点。它可以用于“人类”(用户代理),例如 html 中主页的书签,或用于非人类用户代理的 url。然后您进行内容协商(您的浏览器自动执行的操作)、解析链接等。您无法消除所有带外信息,但一个 URI 非常接近 :) PS:挑剔是件好事...保持诚实关于坚持 REST 原则 ;)
【解决方案2】:

我从事 API 项目已经有一段时间了。 回答您的第一个问题。

是的,如果服务返回值发生变化(例如:名字和姓氏变为全名),您的代码可能会中断。您将不再获得名字和姓氏。

您必须了解 WADL 是一个协议。如果必须更改,则需要通知客户。为避免破坏客户端代码,我们发布了新版本的 API。

1.0 版将包含名字和姓氏,而不会破坏您的代码。我们将发布 1.1 版本,该版本将更改为全名。

因此,简而言之,WADL 将继续存在。只要您使用该版本的 API。您的代码不会中断。如果您想获得全名,则必须移至新版本。技术市场上有很多代码生成插件,生成代码应该不是问题。

回答您的下一个问题,即为什么不使用 WADL 以及如何了解 mime 类型。

WADL 用于代码生成并用作合约。有了它,您可以使用 JAXB 或任何映射框架将 JSON 字符串转换为生成的 bean 对象。

如果不是 WADL,则不需要检查每个元素来确定类型。您可以轻松做到这一点。

var obj = jQuery.parseJSON('{"name":"John"}'); 警报(obj.name ===“约翰”);

如果您有任何问题,请告诉我。

【讨论】:

  • 感谢您的回答。但我觉得你并没有真正回答我想要表达的意思(对不起,如果不清楚)。对于问题 1,我指出 REST 社区对代码生成和 WADL 有一种普遍的“不要这样做”的感觉——为什么会这样?对于问题 2,我指出没有 WADL 就没有合同,因此您不能“期望”在每次调用同一端点时收到相同的结构。如果您查询人员 1,您可能会得到 FirstName,而人员 2 则返回 FirstName 和 Lastname。希望这是有道理的。
  • 好的。为什么不是 WADL?这是因为 WADL 像 WSDL 一样冗长。在 HTTP 世界中,它的全部内容都与状态码有关。我可以在 HTML 文件中解释我的端点和场景的返回代码。如果我可以在浏览器中查看 JSON,我可以对其进行编码。如果端点(或 API 提供者)更改了响应,那么 API 的提供者将更改 API 的版本。提供者不能随意改变响应结构。如果第一个调用获得全名,则名字和姓氏将为空。这就是 JSON 的真实表示。
猜你喜欢
  • 2020-08-22
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 2014-12-17
  • 1970-01-01
  • 2014-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多