1

我正在为应用程序制作一个 CRUD“层”。这将是一个简单的 CRUD 应用程序,例如,存储用户信息、收藏链接等,而不对“事实类型”数据进行操作。它实际上只是存储应用程序的其他部分用来执行工作的用户、权限、规则、策略等内容。

总的来说,我想从这项工作中得到三件事:

  • (a) 访问 CRUD 功能的单一入口点
  • (b) 能够使用任何“客户端”来使用 CRUD 层
  • (c) CRUD 的“简单”可扩展性,其中可以添加新对象并且可以更改旧对象(添加新字段,没有其他内容被删除或更改)。典型的 CRUD 场景?

我在想我应该制作一个 Java 库,通过 HTTP 的“REST-type-URL”(仅表示 REST-URL 方式,如“users/delete/2”)API 将其公开给客户端。这样,我可以满足所有 3 个目标 - CRUD 层可以在 Linux 上,客户端可以在 Windows 上。

在 CRUD 层,我将使用各种东西来实现这一点:ORM、Web 服务器和其他工具。

似乎是正确的方法,但我不禁想,也许这种方法过于理想主义,在我开始实施时可能不起作用。

我是否正在考虑将一组 API 方法塞进 XML 片段的过于简单化的观点?(请注意,我不是在做 XML-RPC,而是这些 XML 片段将只是数据 - 并且 XML 将被发送到特定的 URL,例如 users/update/2,它会在确认 XML 包含后处理 XML用户个人资料的信息

我的想法是对的吗?这个想法是否有一个遥远的工作机会?

任何帮助表示赞赏!

4

4 回答 4

2

是的,它会起作用。但是,您的分布式系统设计基于数据模型非常简单并将保持这种方式的假设。如果您正在构建的应用程序成功,您可以确定将添加新需求并请求新功能。

按照您的建议公开数据层,将您的客户端应用程序与数据模型紧密耦合,并且您对 http 的使用使得进行多请求事务非常困难。我知道你说过你不需要做多请求事务。不是今天,可能是明年?

此应用程序的预期寿命是多少?如果您说超过几年,那么我会重新考虑将数据层暴露给远程客户端的想法。REST 的主要目标之一是将客户端和服务器应用程序解耦,以允许应用程序在很长一段时间内发展。如果您有多个客户端应用程序访问一个分布式服务(如果设计不正确),它可能会很快遇到令人讨厌的维护和版本控制问题。

编辑以回答有关客户需要了解模型的评论中的问题:

关于客户端如何与从服务器接收到的表示进行交互,您可以采取两个不同的方向。

  1. 您可以允许客户端明确了解表示中包含的数据内容。即客户端知道某些 XML 元素中存在用户名和密码。但是,如果您这样做,您应该返回一个特定的媒体类型,例如 application/vnd.mycompany.user+xml。您不应使用 application/xml,因为它不会告诉客户端有关 XML 文档中的内容的任何信息。如果客户端知道“当您转到 url X 时”您会得到“一个包含元素 User 内的 UserName 和 Password 元素的 Xml 文档”,那么您就违反了 REST 的自描述约束。影响是您已将端点耦合到媒体类型,并且实际上将客户端耦合到该端点。“超媒体约束”的意图
  2. 另一种方法是使用更通用的媒体类型,它只是旨在向客户端提供要显示给用户的内容,并向用户提供选项以允许客户端采取行动。html 媒体类型允许您通过提供可用于在两个 div 标签中返回用户名和密码的标记语言来做到这一点。使用 html FORM 标签和 A 标签,客户端可以对该资源执行额外的操作。弄清楚如何以真正的 RESTful 方式使“用户”对象可能具有的所有可能操作可访问,这很棘手,需要相当多的经验,但最终结果是客户端和服务器的解耦非常好。以网络浏览器为例,您需要多久更新一次浏览器,因为网站更改了其内容。

选项二的问题在于,仅使用 HTML 最终用户体验往往受到很大限制,这就是 Javascript 的用武之地。“可选”REST 限制之一是代码下载的使用。Javascript 是从服务器加载的代码,用于在客户端启用其他行为。不幸的是,在我看来,它还为人们提供了创建返回 application/xml 的 RESTful Web 界面然后使用 javascript 来解释该通用格式的能力。此解决方案适用于使用 RESTful API 的网站的原始开发人员,因为如果 xml 文件的内容发生更改,则可以更改 javascript 并将其重新下载到浏览器,一切都很好。然而,对于访问此 API 且无法控制应用程序/xml 内容模型的任何其他第三方开发人员,他们的代码将变得非常脆弱,并且如果 API 内容更改,则可能会中断。询问任何为 Twitter 编写过任何类型客户端的人,他们的应用程序因 Twitter 更改内容而损坏了多少次。

通过使用第一个选项并为内容提供特定的媒体类型,服务器开发人员可以引入名为 application/vnd.mycompany.userV2+xml 的新媒体类型,并且使用内容协商,现有客户端仍然可以接收原始媒体类型和新的可以构建客户端以使用新的媒体类型。url 保持不变,书签没有损坏,因为端点和媒体类型没有耦合。

如果您看到提供 URL 列表和从这些 url 返回的内容的 API 文档,那么很可能这些开发人员没有获得 REST,也不会获得 RESTful 接口提供的好处。具有讽刺意味的是,受害最大的不是那些开发人员,而是试图与 API 交互的第 3 方受害!

于 2009-08-10T15:38:58.187 回答
1

对于纯数据层,你考虑过事务支持吗?

  • 你需要支持交易吗?如果是这样,它们将如何实施?
  • 事务会跨越多个 HTTP 请求吗?(我认为对于纯 REST 实现,您将多次调用非平凡的操作。)例如借记一个帐户并贷记另一个帐户。
  • 谁来控制交易?

如果现在不需要事务控制,您会看到将来需要它吗?这将如何影响您的设计?

问题多于答案。:) 但值得深思。

更新:

我将使用您选择的语言(在您的情况下为 Java)和您需要的任何其他库(例如 ORM)创建标准数据访问层。如果您已经有数据访问层设计,我会遵循它以保持应用程序简单。如果您想在外部(对各种客户端)公开它,我会在我称之为服务/业务层的地方执行此操作(如果功能很简单,没有重用的潜力,那么将两者折叠到一个实现可能是可以的)。在那里,您将处理任何安全性(身份验证、授权等)、数据验证,并可能在内部数据表示和外部表示之间执行任何映射。然后,您可以根据基于 URL 的 API 公开您的服务。

也许我们在谈论同一件事,但我们的语义不同。

于 2009-08-10T07:19:19.890 回答
1

如果您想从多个客户端访问 CRUD 功能,这是一个好主意。一段时间以来,我们一直在做这样的事情。一些可能对您有所帮助的实现细节。

  1. 简单的 HTTP 调用就足够了,不要打扰 REST。要成为 RESTful,您必须遵循诸如(GET 用于读取,PUT 用于创建等)之类的规则。只需使用 GET 即可在浏览器中轻松测试。我们使用 XSLT 将响应格式化为 HTML 表格。

  2. 我们使用一种 XML 模式来处理所有响应。它基本上是 SQL 结果的 XML 表示,它应该足够灵活以处理多个结果集、受影响的行、错误响应、返回代码等。

  3. 具有 XML 的 JSON 表示,因此更容易在 Javascript 中处理。

  4. 我们还添加了一个 SQL 后门,因此可以将任意 SQL 语句发送到数据库。这对于调试非常方便。这种呼叫需要一些安全性。我们只将它暴露给办公网络。

于 2009-08-10T08:49:46.197 回答
0

如果您正在寻找 Java 解决方案,我建议您看看Restlets。您几乎混合了 XML-RPC 和 REST 风格的架构。 以下是 RPC 和 REST 之间的区别。
如果您想以 RESTful 方式执行此操作,则应使用 URI 来确定操作和参数,而不是传递 XML。

于 2009-08-10T07:13:38.153 回答