REST:用于资源表示的不同分离级别的设计模式

时间:2013-03-26 15:10:09

标签: json rest design-patterns

我正在为许多资源设计REST API,我需要维护至少2个相同格式的表示(例如JSON),这些表示只是它们公开的数据量不同。

例如,我有通过REST公开的书籍,出版商和作者。所以我有3个资源集合:bookspublishersauthors。 在申请书籍时,我希望它包含有关其作者和出版商的最低限度信息 - 只需要提供完整代表的名称,ID和超链接。

GET /books/12345
200 OK
{
    id: "12345",
    title: "My Book",
    authors: [
        {id:"111", name:"J. Smith", _href:"/authors/111"},
        {id:"222", name:"J.R.R. Tolkien", _href:"/authors/222"}
    ],
    publisher: {id:"333", name:"HarperCollins", _href:"/publishers/333"},
}

当用户请求时,例如/publishers/333它应该获得更多关于它的信息,而不仅仅是名称和ID:

{
    id: "333",
    name: "HarperCollins",
    address : { ... },
    contact : { ... },
    logo : { ... }
}

在我的应用程序中,我有3个类BookPublisherAuthor,其中Book包含发布者和作者集合。我正在使用Jackson和Spring MVC通过REST API将所有实体公开为JSON。

@RequestMapping("/books/{id}")
@ResponseBody
public Book getBook(String id) {
    return getBookById(id);
}

@RequestMapping("/authors/{id}")
@ResponseBody
public Book getAuthor(String id) {
    return getAuthorById(id);
}

现在问题:

  • 如何判断视图在哪种情况下应该呈现哪个对象的哪个字段?
  • 我应该将每个实体分成两个 - 一个用于简短,另一个用于完整表示(例如AuthorReferenceAuthorPublisherReferencePublisher)。
  • 如果我选择#2选项,我是否更喜欢作曲或概括?
  • 有没有最佳实践如何处理REST应用程序中相同实体表示的不同去除?

2 个答案:

答案 0 :(得分:2)

您是否考虑使用更标准的超媒体格式,例如HAL

这样做,很明显你会在资源和其他资源的链接之间产生差异。例如,它可能最终为:

GET /books/123
200 OK
{
  "id": "123"
  "title": "My Book"
  "_links": {
     "author": [
       { "href": "/authors/111", "title": "J. Smith" },
       { "href": "/authors/321", "title": "Jules Verne" }
     ],
     "publisher": { "href": "/publishers/123", "title": "Harper Collins" }
  }
}

在实施方面,我会说你可以:

  1. 为每个资源表示创建自定义DTO类,方法如下:

    public class BookDto {
        @JsonProperty(value="_links")
        public LinkCollection getLinks() { }
    
        public String getTitle() { }
    }
    
  2. 使用相同的类,但在Jackson序列化之前使用过滤器修改对象,并使用@ JsonProperty / @ JsonIgnore的某种组合。

答案 1 :(得分:0)

1 /根据Spring MVC文档,要通过HTTP序列化您的对象,您必须使用HttpMessageConverter<T> TBook或{Publisher来定义自己的实现Author的类。 {1}}。 http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/remoting.html#rest-message-conversion

2 /没有必要将对象分成两部分。选择Author中选取的字段的逻辑包含在AuthorToHttp implement HttpMessageConverter<Author>中。只需要开发一个AuthorReferenceToHttp implement HttpMessageConverter<Author>,以便在需要通过HTTP发送更少的数据时使用。

另一方面,另一方面可以是AuthorReference extend AuthorAuthor extend AuthorReference,另一方面可以AuthorToHttp implement HttpMessageConverter<Author>AuthorReferenceToHttp implement HttpMessageConverter<AuthorReference>同步,以序列化Author

3 /继承/泛化就足够了。不一定需要模式。

Composite是一个错误的选择,你不需要树结构。根据情况,您需要有关作者的所有数据 - 默认行为 - 或者关于作者的主要数据 - “代理”行为 - 。代理将是一个更好的选择。

4 /不知道。