RESTful 设计,如何在 CRUD 等之外命名页面?

Posted

技术标签:

【中文标题】RESTful 设计,如何在 CRUD 等之外命名页面?【英文标题】:RESTful design, how to name pages outside CRUD et al? 【发布时间】:2011-02-21 06:27:40 【问题描述】:

我正在开发的网站有很多页面超出了我对 RESTful 设计的有限理解范围,本质上是:

Create, Read, Update, Delete, Show, List

这里的问题是:当页面没有整齐地落入 CRUD/show/list 时,什么是标记动作/路线的好系统?我的一些页面一次包含有关多个表的信息。我正在建立一个网站,在某些客户登录后为他们提供“大本营”。它不会给他们任何关于他们自己的信息,所以它不应该是,例如,/customers/show/1。它确实包含有关公司的信息,但该网站上的其他页面以不同的方式执行此操作。当你遇到这些情况时你会怎么做?这个“大本营”是向客户展示的,它主要包含有关公司的信息(但不是唯一的)。

第二种情况:我在客户和公司之间有一个名为“匹配”的表。这些匹配在站点的不同部分以完全不同的方式访问(不同的布局、不同的 CSS 表、访问它们的不同类型的用户等。它们不能都是匹配/显示。标记其他的最好方法是什么?

非常感谢。 =)

【问题讨论】:

REST over HTTP 表示您应该尝试将 GET、PUT、POST、DELETE 映射到资源。 Rails 指的是 Create, Read, Update, Delete, Show, List 之类的操作,而不是 RESTful 设计。 查看我几天前的回答 (***.com/questions/2857323/…)。也许 REST 缺少这些额外的部分,而不是相反。 @Anurag REST 本身并没有定义统一的接口,它只是说你应该使用它始终如一的东西。在大多数情况下,人们使用 HTTP。如果您想向 IETF 提出将这些操作添加到 HTTP 的理由,请不要让我气馁。 【参考方案1】:

我当然不是专家,但是如果您重新考虑您的资源并将它们更严格地视为“名词”或至少是数据列表,那么将任何所需的操作放入 GET、POST、PUT 和删除。例如,您有一个/customers/ 资源,可以假定每个客户都有一个/customers/username/ 资源。也许这给了他们关于自己的信息。您可以将/homebases/username//customers/username/homebase/ 作为您的基本资源。据推测,您将主要通过 GET 访问该 homebase 资源,如果有任何要更新的内容,则 POST (我不希望在 homebase 或仪表板上,因为它是一个聚合资源)。

对于“匹配”,您可以使用 /matchings/customer,company/ 之类的内容(是的,允许使用逗号和分号。逗号通常表示这两个部分与顺序相关,分号表示与顺序无关,尽管没有相关规则)。从该资源中,您可以使用 GET 读取、显示和列出您需要的任何数据(包括作为 GET 请求的主体传递的可选查询参数),使用 POST 进行更新,使用 PUT 进行创建,使用 DELETE 进行删除。使用 GET 中传递的参数,您还可以请求相同数据的不同视图。当然,您可以拥有该匹配的子资源,例如 /matchings/customer,company/invoices/invoice#/

顺便说一句,我喜欢“RESTful Web Services”(2007 O'Reilly)一书。

我希望这有一定的意义并且是有帮助的。 =)

【讨论】:

【参考方案2】:

我认为聚合和复合视图是一个严重的问题。我不得不处理homepage 的问题,它与我所知道的所有 RESTful 都背道而驰。

我的解决方案是将主页或仪表板本身视为一种资源,但这种资源只有 GET 操作才有意义。主页上的 POST/PUT/DELETE 照常定向到特定资源。

相比之下,匹配似乎是一个更容易解决的问题。从您的描述来看,这似乎是客户和公司之间的简单映射,您可以根据查询字符串参数对其进行参数化。

/matchings?companies=X,Y,Z&locations=NY,CA,TX

【讨论】:

我同意在仪表板资源上允许除 GET 之外的任何内容似乎很奇怪,并且如您所说,让仪表板的某些部分更新其他资源会很好。 将仪表板视为资源是一种完全有效的方法,并且仅支持方法子集的资源没有问题。唯一需要注意的是主页资源。创建为不同的人返回不同内容的单个 URL 通常不是一个好主意。最好创建一个/users/bob/homegage 资源。 如果仪表板视图需要经过身份验证的访问权限,那么您可以为所有用户使用相同的 URL - 想想邮件、facebook、twitter 等。 你可以,但是你需要确保你适当地设置了可变标头,以便缓存知道它们不能为不同的用户返回缓存的结果。您也失去了与他人共享网址的好处。总的来说,我发现使用相同的 url 有很多缺点,没有任何优点。 这就是私有数据的全部意义,只有经过身份验证才能访问。无论如何,您都不希望您的邮件等被缓存在中间服务器上,并且与其他人共享您的邮件收件箱/私人数据 url 也没有意义。【参考方案3】:

对于 RESTful 设计,我假设您指的是 RESTful Web 服务,因为基于 REST 的架构具有比这更广泛的意义。

要考虑的主要问题是,基于 REST 的架构几乎在所有情况下都依赖 HTTP 协议。由于 HTTP 指定了一组方法,因此有时这些方法用于创建所谓的 RESTful Web 服务。

但 RESTful Web 服务不遵循任何具体标准(与 SOAP 不同)。常用:

GET - 用于获取现有项目 POST - 用于创建新项目 PUT - 用于更新现有项目 DELETE - 用于删除现有项目

创建、读取、更新和删除 (CRUD) 是任何持久存储的基本功能。

很容易看出,在常见的 RESTful Web 服务中,每个 HTTP 方法都被用于匹配其中一个基本功能,但重点是:不一定非要这样。

还有其他需要考虑的事情,URL 映射是其中之一(因为这是您的问题所关心的问题),安全性是另一个。 POST 请求在 HTTP 正文中发送请求的内容(可以加密),但 GET 请求在 URL 中发送,每个人都可以看到。

如果想开发一种安全(加密)的 RESTful Web 服务,可以使所有请求 HTTPS POST,然后在请求中指定要执行哪些 CRUD 操作,以及在哪些资源上执行。

还可以将 CRUD 概念扩展到更广泛的范围,事实上,几乎在每个应用程序中,都必须这样做。

请记住,CRUD 只是所有其他操作都可以在其中构建的四个基本操作。您无需遵循任何标准,您可以根据您的上下文中的意义指定自己的协议,并牢记所有相关考虑因素(安全性、URL 等)

特别是关于你的问题,你可以有自己的行动,比如show_by_x、show_by_y等。REST警察不会来逮捕你:-)

【讨论】:

SOAP RPC architecture over HTTP is a RESTful architecture 嗯?你能为这个奇怪的说法提供一些支持吗? 我的意思是说明 REST 在更广泛的意义上是如何使用 HTTP 方法的。 SOAP 使用 POST 方法。但是我选择的示例确实很差,因为通常提到 REST 作为 SOAP 的替代品,所以我从我的答案中删除了引用。感谢您指出这一点。【参考方案4】:

REST 和 ORM 是两个不同的东西,因为即使你有一个名为 User 的模型,你也必须拥有一个 users 资源。资源应该在 Rails 控制器级别进行管理

将资源视为模块/部分

例如:您可能希望您的用户在登录后登陆仪表板页面(假设您有两类用户管理员和普通用户),因此您可以分别拥有两种资源

admin_dashboard uer_dashboard

两者都可能只有读取操作

第二种情况:

如果可能,考虑使用类似上述示例的内容(根据不同的用户级别使用不同的资源)

我不是 REST 专家,但希望这会有所帮助:D

干杯, 同龄人

【讨论】:

以上是关于RESTful 设计,如何在 CRUD 等之外命名页面?的主要内容,如果未能解决你的问题,请参考以下文章

无需编程,基于PostgreSQL零代码生成CRUD增删改查RESTful API接口

编写 Node.js RESTful API 的 10 个最佳实践

AngularJs调用Restful实现CRUD - AngularJs

处理多个动作的 RESTful CRUD 函数?

springboot的服务端Restful风格 API接口,在不同场景下,设置不同的请求及传参方式的设计,及其他异常场景解决方案

如何使用 ThinkJS 优雅的编写 RESTful API