RESTful网络服务中复合对象的URI

4

我已经创建了这些路径:

POST /books/4/chapters 
Chapter实体是Book组成部分。它不能没有书籍存在于系统中。现在,在通过上面的URI创建一个章节后,我应该为更新和获取特定章节的答案资源创建另一组URI吗?
GET /books/4/chapters/6还是GET /chapters/6
请记住,一旦您获得了一个级别的主键,通常就不需要再包括其上面的级别,因为您已经有了特定的对象。换句话说,您不应该需要太多的情况下URL比我们上面的/resource/identifier/resource还要深。
来自apigee Web API设计 GET /chapters/6更符合文章所说的,但这也意味着您的对象不再处于其父级范围内(因为它是Book类的组合对象的一部分)。但是我认为这更好,因为章节可以是其他对象的组合,这意味着您会得到长嵌套的URI:
如果所有内容都应处于父级范围内,则为GET /books/4/chapters/5/paragrahps/5
最好的做法是什么呢?
编辑
经过更多思考,最好将URI设置为/books/4/chapters/9等,因为您没有检索没有其父级的特定反馈的代码库等,因为它是一个复合对象?

2
+1 因为这是一个合法的问题。=) - sschrass
1个回答

4
我会采用你提到的方法,例如:
/books/4/chapters -- GET : Retrieve full list of chapters of the book
/books/4/chapters/9 -- GET : Retrieve the 9th chapter of book 4. 

重要的关键词是“of”。它是书籍的一个章节,如果没有书籍,单独呈现出来就毫无意义。仅仅使用“/chapters/9”非常不清晰。你会将其视为完整实体,而实际上它只是书籍的一个子集。
按照上述方法,你将拥有非常清晰的URI。你正在检索一个特定的资源(第9章),这是另一个资源的子资源(因此,你必须提到“超级”资源)。
我真的建议你看一下Symfony团队成员David Zülke的这个精彩的演示文稿。它是一份关于REST的语言不可知的演示文稿。更确切地说,它从16分钟到30分钟讨论了URI,但整个演示文稿都很棒,值得一看。

关于apigee演示的说明

我今天观看了它,虽然在大多数情况下我同意他们的观点。但我看到了一个问题。虽然能够按章节检索可能很好,

/chapter/{its id} -- GET

问题在于,在某些情况下,您想要一本书的第9章,而不是检索238723(不清楚它是否为第9章)。在这种情况下,更明智的做法是通过以下方式检索它:
/books/4/chapters/9 -- GET

但是您仍然意味着,当章节是作品的一部分时,应该可以通过id检索章节,对吗?由于通常不会为这样的对象创建存储库/dao等,它们是书的一部分,因此始终通过书进行操作?至少对我来说,这是最有意义的。 - LuckyLuke
使用最后一种方法,如果您执行了/books/4/chapters/9 -- DELETE,并且总共有20个章节,会发生什么情况?每个章节都有自己的持久ID,但是假设章节顺序是在将章节添加到书中时设置的瞬态属性。这样做是否不好?我的意思是,您将如何实现作为组成部分的章节(或任何其他实体)的漂亮ID? - LuckyLuke
这取决于你如何制作章节的PKeys。它们有自己的ID吗?它们有一个复合键,即book_id和ID(这将是章节数)。是否两者都有ID,但它们还具有唯一的book_id + order(这将是我们的9)?我认为只要在API规范中清楚说明,所有这些情况都可以使用。最重要的是,对于API用户没有歧义(他们在apiegee视频中提到了这一点),因为毕竟,你想要的是使用你的API。 - Hugo Dozois

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接