如何构建REST资源层次结构?

时间:2013-03-06 22:58:04

标签: api rest uri restful-url restful-architecture

我是服务器端Web开发的新手,最近我一直在阅读很多关于实现RESTful API的内容。我仍然坚持的REST API的一个方面是如何构建URI层次结构,以识别客户端可以与之交互的资源。具体来说,我一直在决定如何制作层次结构以及在资源由其他资源类型组成的情况下该怎么做。

这是一个有希望展示我的意思的例子。想象一下,我们有一个Web服务,允许用户从其他用户购买产品。因此,在这个简单的案例中,有两个顶级资源用户产品。这是我开始构建URI层次结构的方式,

对于用户:

/users
      /{id}
           /location
           /about
           /name
           /seller_rating
           /bought
           /sold

对于产品:

/products
         /{id}
              /name
              /category
              /description
              /keywords
              /buyer
              /seller

在这两种情况下,每个层次结构中的对象都引用另一个层次结构中的对象的子集。例如,/users/{id}/bought是某些用户购买的产品列表,它是/products的子集。此外,/products/{id}/seller引用了销售特定产品的用户。

由于这些URI引用其他对象或其他对象的子集,因此API应支持以下内容:/users/{id}/bought/id/description/products/{id}/buyer/location?因为如果支持那些类型的URI,那么阻止像/users/{id}/bought/{id}/buyer/bought/{id}/seller/name这样的东西,或者同样令人费解的东西呢?此外,在这种情况下,您将如何处理路由,因为服务器中的路由器必须解释任意长度的URI?

2 个答案:

答案 0 :(得分:23)

目标是构建方便的资源标识符,不要尝试交叉引用所有内容。您不必在URL表示中重复数据库关系:)

/product/{id}/buyer之类的链接永远不会存在,因为该资源已有标识符:/user/{id}

虽然可以/product/{id}/buyers-list,但因为买家列表是其他环境中不存在的产品属性。<​​/ p>

答案 1 :(得分:13)

您应该以CRUD方式考虑它,每个实体都支持创建,读取,更新和删除(通常分别使用GET,POST,PUT和DELETE HTTP谓词)。

这意味着您的端点通常只会深入一级。例如

用户

GET    /users       - Return a list of all users (you may not want to make this publically available)
GET    /users/:id   - Return the user with that id
POST   /users      - Create a new user. Return a 201 Status Code and the newly created id (if you want)
PUT    /users/:id   - Update the user with that id
DELETE /users/:id  - Delete the user with that id

可能不需要更详细,例如/users/:id/about。虽然它可能会起作用,但可能会略微超出特定范围。

也许在你的情况下你可以加入:

GET    /users/:id/bought - Array of products that the user bought
GET    /users/:id/sold   - Array of products that the user sold

您可以返回id的列表(可以通过产品API获取),或者如果您愿意,可以在发送之前填充产品。如果您确实选择填充它们,则可能不应该填充每个产品引用的用户。这将导致循环包含并且是错误的。

对于产品,在我的引用中我会使用:

GET    /products- Return a list of all products
GET    /products/:id   - Return the products with that id
POST   /products- Create a new product. Return a 201 Status Code and the newly created id (if you want)
PUT    /products/:id   - Update the product with that id
DELETE /products/:id  - Delete the product with that id

GET    /products/:id/buyers     - Array of who bought the product
GET    /products/:id/sellers    - Array of everyone selling the product