我正在为许多资源设计REST API,我需要维护至少2个相同格式的表示(例如JSON),这些表示只是它们公开的数据量不同。
例如,我有通过REST公开的书籍,出版商和作者。所以我有3个资源集合:books
,publishers
和authors
。
在申请书籍时,我希望它包含有关其作者和出版商的最低限度信息 - 只需要提供完整代表的名称,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个类Book
,Publisher
和Author
,其中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);
}
现在问题:
AuthorReference
和Author
,PublisherReference
和Publisher
)。答案 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" }
}
}
在实施方面,我会说你可以:
为每个资源表示创建自定义DTO类,方法如下:
public class BookDto {
@JsonProperty(value="_links")
public LinkCollection getLinks() { }
public String getTitle() { }
}
使用相同的类,但在Jackson序列化之前使用过滤器修改对象,并使用@ JsonProperty / @ JsonIgnore的某种组合。
答案 1 :(得分:0)
1 /根据Spring MVC文档,要通过HTTP序列化您的对象,您必须使用HttpMessageConverter<T>
T
,Book
或{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 Author
或Author extend AuthorReference
,另一方面可以AuthorToHttp implement HttpMessageConverter<Author>
与AuthorReferenceToHttp implement HttpMessageConverter<AuthorReference>
同步,以序列化Author
。
3 /继承/泛化就足够了。不一定需要模式。
Composite是一个错误的选择,你不需要树结构。根据情况,您需要有关作者的所有数据 - 默认行为 - 或者关于作者的主要数据 - “代理”行为 - 。代理将是一个更好的选择。
4 /不知道。