我一直在阅读如何在名词后建模资源以及如何在URI中表示相关资源。
简短背景:
我们说我必须为人创建一个文档。人员数据存在于外部应用程序中,但我们需要在应用程序中创建文档。文档创建的起点是对将从外部应用程序获取人员详细信息的人员执行搜索,然后我们将在数据库中创建/保存文档和人员的详细信息。我觉得在此case人是一个名词,因此是一个资源,无论我们的应用程序是否创建了一个新人。即使该操作不是直接创建一个新人,但似乎没有一个人就不能存在文档。所以创建文档URI应该是
POST /persons/personId/documents
更直观。
但是有一个不同的建议,即人在这里并不是真正的资源,其论点是我们不是在修改Person,因此URI应该是
/documents
所以我的问题:
根据上述论点,人不是资源是对吗?
创建文档的第一种方法不是更好/更直观:/persons/personId/documents
?如果没有Person,就无法创建为Person和文档创建文档的事实。
答案 0 :(得分:2)
关于REST存在很多误解,人们经常就REST中不存在问题的事情进行无休止的讨论。
首先,URI语义在REST中无关紧要,所以忘记名词/动词废话。我看到有人强调试图找出如何将动作转换为名词和HTTP动词,这绝对没有意义。在REST中,整个URI是一个原子标识符,URI内容无关紧要,只有URI标识的内容。当然,我们应该努力建立清晰且组织良好的URI,这清楚地向开发人员传达意图,但这只是一个普遍的良好实践,而不是REST约束。没有RESTful URI这样的东西。什么使URI RESTful是你如何获得它,而不是它的样子。
其次,URI语义是无关紧要的,因为REST APIs must be hypertext driven。相关资源应该由资源表示本身中的链接表示,而不是在URI中,如第一个短语所示。您的客户如何知道创建文档的URI?他们是否在文档中阅读/persons/<personid>/documents
之类的内容并将personid
替换为值?这是您加入StackOverflow时想要阅读的问题吗?您检查URI模板的文档,获取您的用户ID,将其粘贴到URI占位符中?当然不是。您只需关注一个链接,而您并不真正关心URI到底是什么。这就是REST的工作原理。就像网络一样。
因此,当您的客户输入您的API时,他们可以拥有一个根文档,该文档显示与其关联的Person
资源的表示形式以及与该资源的永久链接,以及指向相关资源(包括文档)的链接。 Person
资源的文档可以解释rel=documents
链接如何指向与该人关联的Document
资源集合,以及对同一URI的POST如何创建新Document
1}}资源。正如您所看到的,您所问的并不是REST中的问题,因为“直观”的事情是遵循链接。它可以是/persons/<personid>/documents
或其他任何内容。重要的是您的客户如何获得这些链接。
第三,由URI标识的所有内容都是资源,您与之交互的所有内容都应至少包含一个URI。这意味着如果你正在与除了URI之外的任何东西进行交互 - 例如,你正在身体中发送一个id - 而你正在与之交互的东西无法通过URI访问,那么它就不是一个资源你做错了什么。
所以,如果答案不明确:
如果你有一个Person的URI,它就是一个资源。如果你不这样做,那就不是。
唯一的RESTful方法是遵循链接,URI语义无关紧要。当然,描述性越强,越好,但这取决于您,而不是REST约束。
答案 1 :(得分:1)
存储Person的位置无关紧要。您正在设计一个API,根据定义,它是一个从存储后端抽象的接口。
您提出的URL非常RESTful,因为它正确地模拟了人与文档之间的关系。此外,此URL方案具有所有人员(/persons
)的集合资源的段和一个用于收集属于文档(/persons/{personId}/documents
)的所有文档的段。
只要您不允许
等请求POST /persons
或
PUT /person/{personId}
这将创建一个新人或改变现有人,我认为这种方法没有问题。
答案 2 :(得分:0)
我会说Person是一种资源,因为可以请求有关某个人的信息:他们拥有的文件。
对我而言,URI表达不同资源之间的关系似乎是完全合理的。