在REST api中一次发布复杂对象还是逐步添加子资源?

时间:2014-02-04 22:09:30

标签: java spring rest spring-mvc

假设您有一个通过应用RESTful原则构建的Web服务。您有一个URL,您也可以发布新文章。 /articles是路径。

每篇文章都包含标题,日期,描述等......(原始值)以及更复杂的关系,例如文章应放置的类别,位置等。

在资源上创建资源后,为资源执行GET操作。 /articles/123456您在JSON中获得了所有原始数据(如标题等)以及包含位置,类别等URL的简单字段的响应。我没有在文章中嵌入这些数据。

但是,在创建新文章时,正确的做法是什么?我应该嵌入类别,位置等(更像是与其他复合对象的关系),还是首先使用简单数据发布新文章,然后逐步向其中添加数据?

例如/articles/123456/categories POST

或者这取决于说明创建文章所需数据的业务要求?你会怎么做?

2 个答案:

答案 0 :(得分:0)

拥有可变的子资源(或集合)可能有用或无用。想想API消费者,他将如何使用您的API?还要考虑相关资源的生命周期;那些实体可以靠自己生活吗?考虑到这些事情应该让你很好地了解你是否需要能够自己改变这些子资源/集合。无论如何,我会说从小开始,并将这些资源与文章本身一起发布(并将其与文章一起发布),这是一个明智的起点。您可以随时添加API方法来变更/查询子资源/集合。

答案 1 :(得分:0)

我认为使用多个POST更新/创建每个实体更简单。如果你试图在“大爆炸”中做所有事情,你可能需要编写几个代码来将表单对象拆分成多个实体,然后再添加它们。

例如,假设您正在创建一个新帖子并为其分配两个标签。您的HTML表单就像这样

<form ..>
  <input name="postId" ../>
  <input name="subject" ../>
  <input name="content" ../>
  <input name="tagIds" value="1001"../>
  <input name="tagIds" value="1002"../>
</form>

(我相信)您无法一次性将其映射到Post和Tag实体。因此,您必须创建具有所有这些属性的表单支持对象:

public class NewPostForm {
  private long postid;
  private String subject;
  private String content;
  private List<String> tagIds;
  ..
}

然后,在将它们保存到持久层之前,必须先将它们分成Post和Tags对象。

@RequestMapping(..)
public String createNewPost(@ModelAttribute(..) NewPostForm form,..) {
  Post newPost = .. // create post from form

  List<Tag> tags = .. // create tag collections from form

  // save through persistence layer
}

然而,如果您为每个实体类使用单独的POST,则不需要此NewPostForm类。