【问题标题】:How do you GET a RESTful resource by something other than ID?您如何通过 ID 以外的方式获取 RESTful 资源?
【发布时间】:2009-02-01 06:48:40
【问题描述】:

在某些情况下,我可能需要通过 ID 以外的参数来查找对象。什么是正确的 RESTful 方式来做到这一点?

例如,我可能想通过usernamepassword 找到User,因此严格的RESTful“GET /users/1”是行不通的。

根据the Rails docs,这是获取资源所有实例的 URL 模式:“GET /users”。我可以向其中添加参数:“GET /users?username=joe&password=topsecret”,但这会破坏 GET 请求的官方目的。

【问题讨论】:

  • 可能不应该以任何方式通过网络发送密码,除非您使用 https
  • 即使你使用https,它也会在历史记录中暴露密码。

标签: ruby-on-rails rest


【解决方案1】:

“GET /users?username=joe&password=topsecret”,但这会歪曲 GET 请求的官方目的。”

不,它不会扭曲任何东西。这绝对是正确的 RESTful 方式,并且是在 http 规范中检索动态结果的推荐方式。 REST 不关心 URL 中的内容,只关心它是唯一的。该页面的 url 可以是 http://3f778a9b8a7c778696e 对于所有 REST 架构关心,只要这是到达那里的唯一方法,并且它永远不会引导到其他任何地方。

http 定义了一个用于返回动态结果的查询字符串协议。鉴于数据库的当前状态,您为应用程序提供的查询字符串应该始终返回相同的结果。然后它将是 RESTFUL。 URL 美学与 REST 完全不同。

根据 REST 架构,GET 请求的规则是它总是返回相同的结果(或在相当长的时间内保持相同的结果,以便缓存起作用),并且 GET 没有边效果。 GET 需要是幂等的(总是返回相同的结果,不管你调用了多少次)并且不会导致系统改变状态。那是

当然,您不必使用查询协议。您可以将参数放入正斜杠、分号之间,也可以是 base64 编码的 GUID。这完全取决于你,只要它遵循这些简单的规则。

【讨论】:

  • 很高兴知道。听起来好像 Rails 文档误导了我。他们的例子:“GET /photos”的意思是“显示所有照片的列表”。所以实际上它可以是我想要的任何东西,只要它不改变资源的任何东西。
  • "GET /photos" 表示“列出所有照片”,“GET /photos?x=y&z=wombat”表示“列出所有照片,其中 'x' 为 'y' 且 'z' 为 '袋熊”。
  • 为特定的 url 结构赋予意义是 DHH 做出的审美决定。这是“约定优于配置”:我们猜你正在制作一个 crud 应用程序,所以这些可能是你想要的 URL。但这完全是任意的。它们只是“静态”资源的标识符。
  • 但是做这样的事情也不是完全没有道理的。大多数 web 服务器和 ftp 服务器通过将 url 空间映射到传统文件系统的树结构来为 url 结构分配意义。例如,您可以创建一个引用 2d 或 3d 网格空间的方案,并且仍然是 RESTy。
  • 动态应用程序有点复杂,可能代表了一种非常有趣且非传统的拓扑结构。有时可能需要对您的网址进行创意。
【解决方案2】:

多键不安静,是吗?也许/users/[username]?password=secret。此外,您不想在那里使用密码,而是使用某种 API 密钥,因此 url 看起来像这样:

/users/leethal?secret=da01930adfe82810092

要使用用户名而不是 id,请执行以下操作:

# controller
@user = User.find_by_username!(params[:id])

# model
def to_param
  username
end

【讨论】:

  • 是否仍然需要应用 # model sn-p,即使在 Rails 3.x 上也是如此?
  • 我会这么认为。不过不确定在 Rails 3 中是否还有其他方法。
猜你喜欢
  • 2021-02-12
  • 1970-01-01
  • 2020-12-24
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多