RESTful API中的斜杠


60

我一直在争论如何使用RESTful API中的斜杠。

可以说我有一个称为狗的资源,而每个狗都有从属资源。因此,我们可以执行以下操作:

GET/PUT/POST/DELETE http://example.com/dogs
GET/PUT/POST/DELETE http://example.com/dogs/{id}

但是,如何处理以下特殊情况:

GET/PUT/POST/DELETE http://example.com/dogs/

我个人的观点是,这是向id = =的单个狗资源发送请求null。我认为在这种情况下,API应该返回404。

其他人则说请求正在访问dogs资源,即尾部的斜杠将被忽略。

有人知道最终答案吗?


2
我认为RESTful方法是区分dog / id和dogs(意味着所有狗)。
pdr

摘自《 RESTful Web服务》中的-从属资源:与某些其他“父”资源(例如dogs / {id})相关的资源启用Web的数据库可以将表公开为资源,而将各个数据库行公开为其下属资源。
Gaz_Edge

它正在访问dog资源,尾部的斜杠应被忽略,这意味着它在尝试删除不应应用delete的内容时应获得禁止的响应。我想404也可以接受。但这有关系吗?
本杰明·格林鲍姆

我不懂-谁说你不能删除狗?如果删除狗,它将删除自身和所有单个狗。这就是为什么我认为允许打电话给狗/是有风险的。如果客户打算删除一条狗,但又意外地放弃了{id},该怎么办?结果将是所有狗都将被删除。假设它要求{id} null并返回404
Gaz_Edge,

我会dogsdogs/等同对待。对我来说,很明显这dogs/是一个包含各个狗的目录。它不清楚是什么dogs,但我将其视为等同,就像大多数Web服务器接受目录访问而没有尾随一样/
CodesInChaos

Answers:


50

这些都不是权威性的(因为REST没有确切的含义)。但是从REST的原始论文来看,完整的(不是以/结尾)URL命名了一个资源,而以斜杠“ /”结尾的是一个资源组(可能不是这样写的)。

GET的末尾带有斜杠应该列出可用的资源。

GET http://example.com/dogs/          /* List all the dogs resources */

URL上带有斜杠的PUT应该替换所有资源。

PUT http://example.com/dogs/          /* Replace all the dogs resources */

带有斜杠的URL上的DELETE应该删除所有资源

DELETE http://example.com/dogs/       /* Deletes all the dogs resources */

URL上带有斜杠的POST应该会创建一个新资源,然后可以对其进行访问。为了保持一致,新资源应位于此目录中(尽管许多RESTful架构在此处作弊)。

POST http://example.com/dogs/        /* Creates a new dogs resource (notice singular) */

等等

关于这个主题的维基页面似乎很好地解释了这一点:

请参阅示例https://en.wikipedia.org/wiki/Representationalalstate_transfer#Applied_to_Web_services


它也适合通常的路径/ URL模型,在该模型中,目录通常写在末尾/
CodesInChaos 2013年

4
那么,如果没有尾随访问资源组该/怎么办?

1
@oberlies:这取决于上下文。没有严格的规则,只有最佳实践。该规则总是有期望的,它应该表示您期望的含义。在上面的示例中:GET http://example.com/dogs可能返回有关狗的元信息(不是列表本身,而是有关狗列表的元信息)。也许或者是一个错误。
马丁·约克

1
As the last character within a URI’s path, a forward slash (/) adds no semantic value and may cause confusion. It’s better to drop them completely.这不是唯一不建议使用斜线训练的地方
Laiv

@莱夫我不同意这种观点。但是,请链接更权威的参考(那是一个薄弱的链接)。
马丁·约克

17
Does anyone know the definitive answer?

因为没有正式文档,因此没有关于将服务视为RESTful所需的正式文件。

话虽如此,我只是为了便于使用才允许使用斜杠。从技术上讲,这可以看作是试图访问ID为空的狗。除非他们在您的文档中阅读过,否则不会看到用户进行此跳转。我可以看到一个用户尝试针对您的API编写代码,并仅从习惯上添加了斜杠,并想知道为什么他们想要狗列表时为什么会收到404响应。



由于狗是所有单个狗的父代,因此删除狗将删除所有单个狗及其本身。如果您不这样做,您的超媒体就会崩溃
Gaz_Edge 2013年

@Gaz_Edge:在REST example.com/dogs中,资源是完全独立于任何资源的example.com/dogs/X。因此,DELETE on example.com/dogs不必删除所有的dogs / *(尽管可以删除它的语义)。但是DELETE example.com/dogs/应该删除所有的狗/ *。
马丁·约克

3
我再说一遍,因为关于RESTful没有明确的规则集,所以当您删除/ dogs或/ dogs /时会发生什么,将基于您期望API使用者的期望。他们是否真的可能会希望删除一个请求中的所有狗?如果是这样,则以这种方式实施,否则请给出405 Method Not Allowed响应。
迈克,

1
我知道这是一个旧线程,但是最近我一直在想这个问题。对于它的价值,在OS X的Bash shell对待foofoo/foo////相同的。从根本上讲,它似乎消除了空的路径段。因此,如果您对REST服务采用相同的方法,dogs并且dogs/将引用相同的内容。
格雷格·布朗

2

两种方式。

方法一

对于可能包含子代的任何资源,请始终使用斜杠。

只需考虑在包含文件的public_html目录中使用“ GET”即可。

当hello.html是文件时,不可能:

/hello.html
/hello.html/youagain.html

但是当hello.html是目录时可以使用:

/hello.html/     (actually /hello.html/index.html)
/hello.html/youagain.html

因此,如果“ hello.html”永远可以有子级,那么永远都是“ /hello.html/”和“ /hello.html/index.html”(或简称为“ /hello.html/”)列出这些子级。

方法二

放聪明点”。

$ find
.
./hello.html
./hello.html/index.html

find命令并不关心hello.html的类型。目录或文件,不在乎,它是对象的名称。当我们编写“ cp youagain.html hello.html”时,cp可以弄清楚如何处理hello.html。cp很聪明。您的网络服务器也很聪明。它具有路径处理库。它具有路由。它可以统计并告诉您名称是对象还是目录。它可以重定向等等,甚至可以为两者提供相同的响应。这太棒了!!!方式。太多技术了。在我们可以做所有这些事情的时候,谁曾想简单地连接路径字符串?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.