RESTURL设计

RESTURL设计,rest,get,put,Rest,Get,Put,让我们为您创建一个如下url: POST/departments,创建一个新部门 和POST/employees,这将创建一个新员工 这两个url都返回新创建的资源的位置头,等等 假设一名员工可以属于多个部门 您将如何构造相应的URL,最重要的是 是否使用POST或PUT执行此操作?例如:将账单添加到 图书部,你会使用: POST/department/book/employees/Bill 或: 在我看来,前者在语义上更为正确,因为不管怎样,在POST正文中,我有更多的数据来描述这种新关系。而

让我们为您创建一个如下url:

POST/departments
,创建一个新部门
POST/employees
,这将创建一个新员工

这两个url都返回新创建的资源的位置头,等等

假设一名员工可以属于多个部门

您将如何构造相应的URL,最重要的是 是否使用POST或PUT执行此操作?例如:将账单添加到 图书部,你会使用:

POST/department/book/employees/Bill

或:

在我看来,前者在语义上更为正确,因为不管怎样,在
POST
正文中,我有更多的数据来描述这种新关系。而且

GET/employee/Bill
返回的主体与以下主体不同:
GET/departments/book/employees/Bill

所以对我来说,添加关系就像创建一个新的资源。然而,我不喜欢这样的事实
POST/departments/Books/employees/Bill
我在URL中显式地命名新资源。

假设您事先知道员工的姓名,似乎最简单的方法就是使用PUT

PUT /departments/books/employees/bill
如果资源“账单”是全新的,则返回201。如果“票据”已经存在,则返回200

GET /departments/books/employees/bill


应返回相同的数据。我不知道为什么在这两种情况下,如果“Bill”是同一个资源,它就不会出现。

假设您事先知道员工的姓名,那么使用PUT似乎是最简单的方法

PUT /departments/books/employees/bill
如果资源“账单”是全新的,则返回201。如果“票据”已经存在,则返回200

GET /departments/books/employees/bill


应返回相同的数据。我不知道为什么在这两种情况下,如果“Bill”是同一个资源,它就不会这样做。

你的URI看起来像什么并不重要,基于REST的系统不在乎

GET {someUrlToDept}
=>
200 OK
Content-Type: application/hal+xml

<resource>
    <DepartmentName>Books</DepartmentName>
    <links>
        <link rel="http://myapi.com/rels/employees" href="{someUrlToEmployeesForThisDept}"/>
    </links>
<resource>

POST {someUrlToEmployeesForThisDept}
Content-Type : application/hal+xml

<resource>
    <EmployeeName>Bill</EmployeeName>
    <OtherStuff>...</OtherStuff>
</resource>
GET{someUrlToDept}
=>
200行
内容类型:应用程序/hal+xml
书
POST{someUrlToEmployeesForThisDept}
内容类型:应用程序/hal+xml
比尔
...

您的URI看起来如何并不重要,基于REST的系统并不关心

GET {someUrlToDept}
=>
200 OK
Content-Type: application/hal+xml

<resource>
    <DepartmentName>Books</DepartmentName>
    <links>
        <link rel="http://myapi.com/rels/employees" href="{someUrlToEmployeesForThisDept}"/>
    </links>
<resource>

POST {someUrlToEmployeesForThisDept}
Content-Type : application/hal+xml

<resource>
    <EmployeeName>Bill</EmployeeName>
    <OtherStuff>...</OtherStuff>
</resource>
GET{someUrlToDept}
=>
200行
内容类型:应用程序/hal+xml
书
POST{someUrlToEmployeesForThisDept}
内容类型:应用程序/hal+xml
比尔
...

您的问题没有唯一的答案。当URI包含“A/B”时,A和B之间的关系留给开发人员(AFAIK)

然而,我认为URI应该遵循最小意外的原则,因此含义有限

对我来说,A/B只能表示三种可能的关系:

  • “B是概念A的一个实例”
  • “B是实例a的一部分的概念”
  • “A是一个概念,B是一个概念,B是一种A”
  • 你的问题是关于案例2的使用。我希望案例2仅用于“是”关系

    如果我将此逻辑应用于回答您的问题,那么员工是否属于特定部门

    当然不是,因为你写道一名员工可以为多个部门工作。“员工”和“部门”之间的关系是一种“为之工作”的关系,它是一种关联,而不是一种组合。因此,我不主张使用:

    /departments/Books/employees/Bill
    
    我认为一个明确的链接:

    /departments/Books
    
    ressource,指向:

    /employees/Bill
    

    从长远来看,ressource可能更清晰,更不容易被误解。

    您的问题没有唯一的答案。当URI包含“A/B”时,A和B之间的关系留给开发人员(AFAIK)

    然而,我认为URI应该遵循最小意外的原则,因此含义有限

    对我来说,A/B只能表示三种可能的关系:

  • “B是概念A的一个实例”
  • “B是实例a的一部分的概念”
  • “A是一个概念,B是一个概念,B是一种A”
  • 你的问题是关于案例2的使用。我希望案例2仅用于“是”关系

    如果我将此逻辑应用于回答您的问题,那么员工是否属于特定部门

    当然不是,因为你写道一名员工可以为多个部门工作。“员工”和“部门”之间的关系是一种“为之工作”的关系,它是一种关联,而不是一种组合。因此,我不主张使用:

    /departments/Books/employees/Bill
    
    我认为一个明确的链接:

    /departments/Books
    
    ressource,指向:

    /employees/Bill
    

    从长远来看,ressource可以更清晰,更不容易被误解。

    是有道理的,但是我认为PUT的状态代码应该是204(无内容)。由于员工“Bill”有一些特定于部门的字段(它们实际上来自db中的N:N关系),严重的返回得到不同的表示。是的,204也可以。只是不是201,因为没有创建资源。这是有道理的,但是我认为PUT的状态代码应该是204(没有内容)。由于员工“Bill”有一些特定于部门的字段(它们实际上来自db中的N:N关系),严重的返回得到不同的表示。是的,204也可以。不是201,因为资源没有被创建。我想你把REST和HATEAOS@ChadGrant我确实对很多事情感到困惑,但我很确定这不是其中之一:-)我不想变得尖刻,但问题是关于restful url的,我不认为“someUrlToDept”对于这个问题非常有帮助。@ChadGrant没有Restful URL,这是一个矛盾。URL对于REST客户端来说必须是不透明的。仍然认为你没有抓住问题的关键。不管