嵌套模型的类似于RESTful的CRUD操作url模式

时间:2012-08-31 02:21:52

标签: http rest webserver associations restful-url

通常,模型的CRUD操作url模式可以是这样的(假设模型是Post):

new: /posts/new(get)
create:/posts/(post)
edit:/posts/edit(get)
update:/posts/1(put)
get:/posts/1(get)

但是,如果存在嵌套模型“注释”。

“邮政”和“评论”之间的联系是一对多的。

那么CURD操作的url模式应该与注释一样?

new: /posts/1/comments/new   or /comments/new
create:?
edit:?
update:?
.......

最佳做法是什么?


更新

评论的网址似乎应该是这样的:

Get one comment for one post: /posts/1/comments/1

create: /posts/1/comments

update: /posts/1/comments/1

delete: /posts/1/comments/1

现在我对更新和删除操作感到困惑。

更新和删除:/posts/1/comments/1

是否已指定评论ID,因此我想知道网址中的/posts/1是否必要?

2 个答案:

答案 0 :(得分:4)

我认为关键在于评论是否由帖子资源“包含”。请记住,RESTful网址应该是固定链接,因此在所有方案中,特定注释的结束点不得更改。它听起来像是被包含在内,所以url模式可以将注释嵌套在帖子中。如果不是这种情况(例如评论可以转移到另一个帖子,如果嵌套会改变网址),那么你想要一个更平坦的结构,其中/ post / {id} url由帖子资源引用。)

关键是如果它是一个RESTful“超媒体API”,那么就像网站一样,它经常链接到嵌套或引用的资源。它不依赖于客户端必须理解REST模式或关于什么端点包含引用或包含的特殊知识 资源。

http://blog.steveklabnik.com/posts/2012-02-23-rest-is-over

如果'评论'是'post'资源下的资源:

([httpVerb] / url)

得到一个帖子:

[get] /posts/{id}
body has a couple options - either it contains the full deep comments array
(depends on how much data, chat pattern)
{
    id:xxx,
    title:my post,
    comments: [...]
}

... or it just contains the post resource with a url reference to the comments e.g.
{
   id: xxx,
   title: my post,
   commentsUrl: /posts/xxx/comments
}

could also have an option like this (or other options to control depth):
[get] /posts/{id}?deep=true

在帖子中收集评论集合:

[get] /posts/{id}/comments
returns 200 and an array of comments in the response body

为帖子创建评论:

[post] /posts/{id}/comments
body contains json object to create
returns a 201 created

在帖子下编辑评论:

[patch|post] /posts/{id}/comments/{id}
body contains json object with subset of fields/data to update
returns a 200

替换帖子:

[put] /posts/{id}/comment/{id}
body contains json object to *replace*
returns a 200

如果每篇帖子有大量评论,您还可以考虑分页模式:

{
    id: xxx,
    title: myPost,
    pages:6,
    commentsUrl:/posts/xxx/comments/page/1
}

然后:

/posts/{id}/comments/pages/{pageNo}

{
    nextPage: /posts/xxx/comments/2,
    pages:7,
    comments:
    [ { ...,...,}]
}

每个页面都会引用下一页,页面计数和该页面的注释数组。如果你使用了分页模式,那么数组中的每个注释都会有一个引用个人注释的URL。

如果你发现自己在网址中添加了一个动作,那么你可能做错了什么。好读:http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http

答案 1 :(得分:0)

您希望使用规范网址进行删除/更新,这将是完整的。更重要的是,您不应该将来自数据库的主键值公开为公共API中的ID,即您的宁静URL空间。根据数据库更新,从备份还原或其他任何内容,这些值将来可能会发生变化,具体取决于供应商。并且您不希望基础架构更改,如果您可以提供帮助,则会使您的所有URL无效。

如果您使用的是/posts/{postnum}/comments/{commentnum},则可以为每个帖子从1开始为公共注释ID编号,从而制作更短,更好的网址。