我正在开发一个 REST API。关键对象(“名词”)是“项目”,每个项目都有一个唯一的 ID。例如,获取 ID 为 foo 的项目的信息:
GET http://api.example.com/v1/item/foo
可以创建新项目,但客户无法选择 ID。相反,客户端会发送一些代表该项目的信息。所以要创建一个新项目:
POST http://api.example.com/v1/item/
hello=world&hokey=pokey
使用该命令,服务器会检查我们是否已经有 info 的项目hello=world&hokey=pokey
。所以这里有两种情况。
情况一:商品不存在;它被创建了。这个案子很简单。
201 Created
Location: http://api.example.com/v1/item/bar
情况2:该项目已经存在。这就是我苦苦挣扎的地方……不确定要使用的最佳重定向代码是什么。
301 Moved Permanently
? 302 Found
? 303 See Other
? 307 Temporary Redirect
?Location: http://api.example.com/v1/item/foo
我研究了Wikipedia 描述和RFC 2616,但这些似乎都不是完美的。以下是我在这种情况下寻找的具体特征:
重定向是永久性的,因为 ID 永远不会改变。因此,为了提高效率,客户端可以并且应该直接向 ID 端点发出所有未来的请求。这表明 301,因为其他三个是临时的。
重定向应该使用 GET,即使这个请求是 POST。这表明 303,因为从技术上讲,所有其他人都应该重用 POST 方法。在实践中,浏览器将使用 GET 获取 301 和 302,但这是一个 REST API,而不是普通用户在浏览器中使用的网站。
它应该是广泛可用且易于使用的。具体来说,303 是 HTTP/1.1,而 301 和 302 是 HTTP/1.0。我不确定这是多大的问题。
在这一点上,我倾向于 303 只是为了在语义上正确(使用 GET,不要重新发布)并且只是在“临时”部分吸收它。但我不确定 302 是否会更好,因为实际上它与 303 的行为相同,但不需要 HTTP/1.1。但是如果我沿着这条线走,我想知道301是否因为同样的原因加上“永久”部分更好。
想法赞赏!
编辑:让我试着用一个更具体的例子来更好地解释这个“获取或创建”操作的语义:URL 缩短。无论如何,这实际上更接近我的应用程序。
对于 URL 缩短器,迄今为止最常见的操作是按 ID 检索。例如对于http://bit.ly/4Agih5,bit.ly 接收到 4Agih5 的 ID 并且必须将用户重定向到其相应的 URL。
bit.ly 已经有一个 API,但它并不是真正的 RESTful。为了举例,让我编写一个更 RESTful 的 API。例如,查询 ID 可能会返回有关它的各种信息(例如分析):
GET http://api.bit.ly/item/4Agih5
现在如果我想提交一个新的 URL 到 bit.ly 来缩短,我事先不知道我的 URL 的 ID,所以我不能使用 PUT。我会改用 POST 。
POST http://api.bit.ly/item/
url=http://stackoverflow.com/
(但已编码)
如果 bit.ly 之前没有看到此 URL,它将为其创建一个新 ID,并通过 201 Created 将我重定向到新 ID。但如果它看到了那个 URL,它仍然会重定向我而不做任何更改。这样,我可以通过任何一种方式点击该重定向位置以获取缩短 URL 上的信息/元数据。
就像这个 URL 缩短示例一样,在我的应用程序中,冲突并不重要。一个 URL 对应一个 ID,仅此而已。所以 URL 之前是否被缩短并不重要;无论哪种方式,将客户端指向它的 ID 都是有意义的,无论该 ID 是否需要首先创建。
所以我可能不会改变这种方法;我只是在询问最好的重定向方法。谢谢!