问题描述
假设我有一个现有的应用程序,它有两个端点/people 和/pants.调用 GET/people 返回:
[{"name":"约翰",年龄":37,裤子":[{"颜色":"绿色","品牌":"李维斯",尺寸":中等"},{"颜色":"靛蓝","品牌":"jncos","size":"中等大腿"}]},{"name":"六月",年龄":23,裤子":[{"颜色":"粉红色","品牌":"差距",尺寸":小"}]}]如果我要使用 Spring Data Rest 并调用 GET/person 我会收到如下信息:
{_链接":{下一个":{"href":"http://myapp.com/people?page=1&size=20"},自己":{"href":"http://myapp.com/people{&page,size,sort}",模板化":真},搜索":{"href":"http://myapp.com/people/search"}},_嵌入":{人们":[{"name":"约翰",年龄":37,_链接":{自己":{"href":"http://myapp.com/people/john"},裤子":{"href":"http://myapp.com/people/john/pants"}}},{"name":"六月",年龄":23,_链接":{自己":{"href":"http://myapp.com/people/june"},裤子":{"href":"http://myapp.com/people/june/pants"}}}]}}
假设我有一堆我不想更改的现有客户端 - 有没有办法在某些情况下禁用响应的超媒体部分(例如 Accept="application/json")但启用为其他人(Accept="hal+json")?
谢谢!
更新
好的 - 所以这让我很懊恼,我想做的事情不受支持.我理解为什么 SDR 强烈倾向于超媒体......但我不相信提供基于标题禁用"超媒体的能力,因此提供更多选项是一件坏事.
除此之外,我有点不确定如何通过我自己的控制器实际实现这一点.如果我创建一个控制器并尝试使用 `produces = "application/json" 覆盖 /people
RequestMapping,我可以使用 Accept="application/json" 取回原始"json,但是如果我通过 Accept="application/hal+json" 我得到一个带有找不到可接受的表示"的 406.看起来 SDR 资源映射没有映射到内容类型......有什么建议吗?
简短的回答是,没有 hatoas 就不能使用 spring-data-rest.如果您想在没有 hatoas 的情况下构建您的 Web 服务,您必须编写自己的控制器(它仍然可以使用 spring-data 存储库).
在这篇SO帖子中引用Oliver Gierke:
实际上我的重点是:服务器只是在做体面的 REST.如果破坏了客户端,需要修复的是客户端(调整).所以超媒体方面是 Spring 的基础数据 REST,我们不会退出.那可能不是满足你的具体情况,但应该回答这个问题至少 :).– 奥利弗吉尔克
So let's say I have an existing application that has two endpoints /people and /pants. Calling GET /people returns:
[
{
"name":"john",
"age":37,
"pants":[
{
"color":"green",
"brand":"levis",
"size":"medium"
},
{
"color":"indigo",
"brand":"jncos",
"size":"medium-with-huge-legs"
}
]
},
{
"name":"june",
"age":23,
"pants":[
{
"color":"pink",
"brand":"gap",
"size":"small"
}
]
}
]
If i were to use Spring Data Rest and call GET /person i'd receive something like:
{
"_links":{
"next":{
"href":"http://myapp.com/people?page=1&size=20"
},
"self":{
"href":"http://myapp.com/people{&page,size,sort}",
"templated":true
},
"search":{
"href":"http://myapp.com/people/search"
}
},
"_embedded":{
"people":[
{
"name":"john",
"age":37,
"_links":{
"self":{
"href":"http://myapp.com/people/john"
},
"pants":{
"href":"http://myapp.com/people/john/pants"
}
}
},
{
"name":"june",
"age":23,
"_links":{
"self":{
"href":"http://myapp.com/people/june"
},
"pants":{
"href":"http://myapp.com/people/june/pants"
}
}
}
]
}
}
Let's say I have a bunch of existing clients that I don't want to have to change - is there any way to disable the hypermedia portions of the response in some cases (say Accept="application/json") but enable it them for others (Accept="hal+json")?
Thanks!
Updated
Okay - so it appears that much to my chagrin, what I'm looking to do is not supported. I understadn why SDR is are strongly leaning toward Hypermedia... but I don't buy that providing the capability to "disable" hypermedia based on a header thus providing more options is a bad thing.
That aside, I'm a bit unsure of how to actually achieve this via my own Controllers. If I create a Controller and attempt to override the /people
RequestMapping with `produces = "application/json" I am able to get the "raw" json back with Accept="application/json" but if i pass Accept="application/hal+json" I get a 406 with "Could not find acceptable representation". It looks like the SDR resource mappings aren't mapped with a content type ... any suggestions?
The short answer is, you can't use spring-data-rest without hateoas. If you want to build your web service without hateoas, you'll have to write your own controllers (which can still use spring-data repositories).
Quoting Oliver Gierke in this SO post:
这篇关于可选择在 Spring Data Rest 中禁用 HATEOAS 格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!