我正在努力使用HATEOAS实现 Spring MVC 3.x RESTful 服务的正确方法。考虑以下约束:
- 我不希望我的域实体被 web/rest 结构污染。
- 我不希望我的控制器被视图结构污染。
- 我想支持多个视图。
目前我有一个很好的 MVC 应用程序,没有 HATEOAS。域实体是纯 POJO,没有嵌入任何视图或 web/rest 概念。例如:
class User {
public String getName() {...}
public String setName(String name) {...}
...
}
我的控制器也很简单。它们提供路由和状态,并委托给 Spring 的视图解析框架。请注意,我的应用程序支持 JSON、XML 和 HTML,但没有域实体或控制器具有嵌入的视图信息:
@Controller
@RequestMapping("/users")
class UserController {
@RequestMapping
public ModelAndView getAllUsers() {
List<User> users = userRepository.findAll();
return new ModelAndView("users/index", "users", users);
}
@RequestMapping("/{id}")
public ModelAndView getUser(@PathVariable Long id) {
User user = userRepository.findById(id);
return new ModelAndView("users/show", "user", user);
}
}
所以,现在我的问题 - 我不确定支持 HATEOAS 的干净方式。这是一个例子。假设当客户端请求一个 JSON 格式的用户时,它会像这样:
{
firstName: "John",
lastName: "Smith"
}
还假设当我支持 HATEOAS 时,我希望 JSON 包含一个简单的“自我”链接,然后客户端可以使用该链接来刷新对象、删除它或进行其他操作。它还可能有一个“朋友”链接,指示如何获取用户的朋友列表:
{
firstName: "John",
lastName: "Smith",
links: [
{
rel: "self",
ref: "http://myserver/users/1"
},
{
rel: "friends",
ref: "http://myserver/users/1/friends"
}
]
}
不知何故,我想将链接附加到我的对象。我觉得这样做的正确位置是在控制器层,因为控制器都知道正确的 URL。此外,由于我支持多个视图,我觉得正确的做法是在控制器中装饰我的域实体,然后再将它们转换为 JSON/XML/Spring 的视图解析框架中的任何内容。一种方法可能是使用包含链接列表的通用 Resource 类包装有问题的 POJO。需要进行一些视图调整才能将其压缩成我想要的格式,但它是可行的。不幸的是,嵌套资源不能以这种方式包装。想到的其他事情包括添加到 ModelAndView 的链接,然后自定义 Spring 的每个开箱即用的视图解析器以将链接填充到生成的 JSON/XML/等中。我不做什么 不想要的是不断手工制作 JSON/XML/等。以适应开发过程中来来去去的各种链接。
想法?