RESTAPI中的资源:是还是不是?

RESTAPI中的资源:是还是不是?,rest,Rest,我一直在阅读关于资源应该如何按照名词建模以及相关资源应该如何在URI中表示的内容 短背景: 假设我必须为人创建一个文档。人员数据存在于外部应用程序中,但我们需要在应用程序中创建文档。文档创建的起点是对person执行搜索,搜索将从外部应用程序获取person的详细信息,然后我们将在数据库中创建/保存文档和person的详细信息。我觉得在这种情况下,person是一个名词,因此是一种资源,而不管我们的应用程序是否创建新的人与否。即使操作不是直接创建新的人,文档似乎离不开人。因此,createdoc

我一直在阅读关于资源应该如何按照名词建模以及相关资源应该如何在URI中表示的内容

短背景:

假设我必须为人创建一个文档。人员数据存在于外部应用程序中,但我们需要在应用程序中创建文档。文档创建的起点是对person执行搜索,搜索将从外部应用程序获取person的详细信息,然后我们将在数据库中创建/保存文档和person的详细信息。我觉得在这种情况下,person是一个名词,因此是一种资源,而不管我们的应用程序是否创建新的人与否。即使操作不是直接创建新的人,文档似乎离不开人。因此,createdocuments URI应该是

POST /persons/personId/documents
这更直观

但这里有一个不同的建议,即person并不是真正的资源,其论点是我们并没有修改person,因此URI应该是

/documents
所以我的问题是:

  • 根据上述论点,说这个人不是资源是正确的吗

  • 第一种方法创建文档不是更好/更直观吗:
    /persons/personId/documents
    ?事实上,将为某人创建文档,并且在没有此人的情况下无法创建文档

  • 我想说,人是一种资源,因为它可以请求关于特定人的信息:他们拥有的文档

  • 事实上,在我看来,URI表达不同资源之间的关系似乎是完全合理的


  • 人被存放在哪里并不重要。您正在设计一个API,根据定义,它是一个从存储后端抽象出来的接口

    您建议的URL是非常RESTful的,因为它正确地模拟了人员和文档之间的关系。此外,此URL方案有一个用于收集所有人的资源的段(
    /persons
    ),还有一个用于收集属于某个文档的所有文档(
    /persons/{personId}/documents

    只要你不允许这样的请求

    POST /persons
    


    这将创造一个新的人或改变一个现有的人,我认为这种方法没有问题。

    关于休息有很多误解,人们经常没完没了地讨论一些在休息中不是问题的东西

    首先,URI语义在REST中是不相关的,所以忘记名词/动词无意义。我曾看到人们在紧张地试图找出如何将一个动作转换为名词和HTTP动词,这是毫无意义的。在REST中,整个URI是一个原子标识符,URI内容并不重要,只是URI标识的内容。当然,我们应该努力创建清晰且组织良好的URI,以便向开发人员清楚地传达意图,但这只是一个一般的良好实践,而不是REST约束。没有RESTful URI这样的东西。使URI RESTful的是您如何获取它,而不是它的外观

    其次,URI语义是不相关的,因为。相关资源应该由资源表示本身中的链接表示,而不是像您的第一句话所说的那样,由URI中的链接表示。您的客户如何知道创建文档的URI?他们是否在文档中阅读类似于
    /persons//documents
    的内容,并用值替换
    personid
    ?当你加入StackOverflow并想阅读你的问题时,你就是这么做的吗?检查文档中的URI模板,获取用户id,然后将其粘贴到URI占位符中?当然不是。您只需跟随一个链接,并不真正关心URI到底是什么。这就是REST的工作原理。就像网络本身一样

    因此,当您的客户机输入API时,他们可以拥有一个根文档,其中显示与他们关联的
    人员
    资源的表示形式和到该资源的永久链接,以及到相关资源(包括文档)的链接。
    Person
    资源的文档可以解释
    rel=documents
    链接如何指向与该人员相关联的
    Document
    资源集合,以及如何向同一URI发布创建新的
    Document
    资源。正如您所看到的,您所问的在REST中并不是真正的问题,因为“直观”的做法是遵循链接。它可以是
    /persons//documents
    或任何其他内容。重要的是你的客户如何获得这些链接

    第三,由URI标识的所有内容都是一个资源,您与之交互的所有内容都应该至少有一个URI。这意味着,如果您正在与URI以外的任何东西进行交互(例如,您正在正文中发送一个id),并且您正在与之交互的东西无法通过URI访问,那么它不是资源,您正在做一些错误的事情

    因此,如果答案不清楚:

  • 如果您有一个Person的URI,那么它就是一个资源。如果你没有,那就不是

  • 唯一的RESTful方法是遵循链接,URI语义无关紧要。当然,URI的描述性越强越好,但这取决于您,而不是REST约束

  • PUT /person/{personId}