我想在我的Chrome浏览器中内联打开"application/hal + json"响应.问题是Chrome浏览器无法识别HAL响应并下载它.之前我总是使用Chrome的JSON视图扩展来检查我的JSON响应.但是,自从交换到HAL后,它会立即下载我的回复,因此我无法再查看它了.
例如,Level 3 RESTful API具有自定义媒体类型application/vnd.service.entity.v1+json.在我的情况下,我使用HAL来提供我的JSON中相关资源之间的链接.
我不清楚使用HAL + JSON的自定义媒体类型的正确格式.我现在的样子,看起来像application/vnd.service.entity.v1.hal+json.我最初使用application/vnd.service.entity.v1+hal+json,但+hal后缀未注册,因此违反了RFC6838的4.2.8节.
现在Spring HATEOAS支持开箱即用的JSON链接,但对于HAL-JSON,你需要使用@EnableHypermediaSupport(type=EnableHypermediaSupport.HypermediaType.HAL).在我的例子中,因为我使用Spring Boot,所以我将它附加到我的初始化类(即扩展的类SpringBootServletInitializer).但Spring Boot无法识别我的自定义媒体类型.所以为此,我必须弄清楚如何让它知道它需要使用HAL对象映射器来处理表单的媒体类型application/vnd.service.entity.v1.hal+json.
对于我的第一次尝试,我将以下内容添加到Spring Boot初始化程序中:
@Bean
public HttpMessageConverters customConverters() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(Arrays.asList(
new MediaType("application", "json", Charset.defaultCharset()),
new MediaType("application", "*+json", Charset.defaultCharset()),
new MediaType("application", "hal+json"),
new MediaType("application", "*hal+json")
));
CurieProvider curieProvider = getCurieProvider(beanFactory);
RelProvider relProvider = beanFactory.getBean(DELEGATING_REL_PROVIDER_BEAN_NAME, RelProvider.class);
ObjectMapper halObjectMapper = beanFactory.getBean(HAL_OBJECT_MAPPER_BEAN_NAME, ObjectMapper.class);
halObjectMapper.registerModule(new Jackson2HalModule());
halObjectMapper.setHandlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(relProvider, curieProvider));
converter.setObjectMapper(halObjectMapper);
return new HttpMessageConverters(converter); …Run Code Online (Sandbox Code Playgroud) 我见过HAL规范中描述的CURIEs .乍一看,它看起来像是一种为URI提供模板的方法.但是,我也看到它突出地提到它可以用来访问文档rel.哪一个?它只是一个模板机制吗?有没有人有一个好的用例的例子?
此外,以下是CURIE的合法使用吗?或者它应该只用于提供文件rel?
{
"id": 1,
"name": "Social Media Bundle",
"_links": {
"self": {
"href": "http://my.api.com/bundles/1"
},
"curies": {
"name": "bundle",
"href": "http://my.api.com/bundles/1{rel}"
"templated": true
},
"bundle:channels": {
"href": "/channels"
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里bundle:channels将扩展为http://my.api.com/bundles/1/channels.
我已经开始设计一个API,并决定让它符合REST/HATEOAS.API的切入点应该是什么?
这似乎是一个常见的,GET /但从我所读到的,它可能在逻辑上更有意义使用OPTIONS /,因为实际上没有/用于检索的资源.
我在这里给出了两个例子,使用JSON的HAL语法作为超媒体格式.
请求:
GET / HTTP/1.1
Host: example.com
Run Code Online (Sandbox Code Playgroud)
响应:
HTTP/1.1 200 OK
Date: …
Content-Type: application/json;charset=utf-8
Content-Length: 143
{
"_links": {
"self": {
"href": "/"
},
"penguins": {
"href": "/penguins"
}
}
}
Run Code Online (Sandbox Code Playgroud)
请求:
OPTIONS / HTTP/1.1
Host: example.com
Run Code Online (Sandbox Code Playgroud)
响应:
HTTP/1.1 200 OK
Date: …
Allow: OPTIONS
Content-Type: application/json;charset=utf-8
Content-Length: 143
{
"_links": {
"self": {
"href": "/"
},
"penguins": {
"href": "/penguins"
}
}
}
Run Code Online (Sandbox Code Playgroud) 我对REST比较陌生,但我一直在做关于RESTful应该是什么的功课.现在我正在尝试为我的模型创建一个RESTful api,它实现了一个与其他模型有关系的JSON + HAL序列化器.
python中的示例模型:
class Category(Model):
name = CharField()
parent = ManyToOneField(Category)
categories = OneToManyField(Category)
products = ManyToManyField(Product)
class Product(Model):
name = CharField()
price = DecimalField()
related = ManyToManyField(Product)
categories = ManyToManyField(Category)
Run Code Online (Sandbox Code Playgroud)
假设我们有一个类别"目录",其子类别"食物"与产品"汉堡"和"热狗"都是相关的.
第一个问题.类别和产品应该是资源,所以他们需要一个URI,我应该在我的模型实现一个URI区域,并将其存储在数据库中或以某种方式在运行时计算的话,大约多标识符(URI)是什么?
第二个问题.可发现性,在Hal格式中应该"GET /"和不同的节点返回以使api容易被自己发现.
{
"_links":{
"self":{
"href":"/"
},
"categories":[
{
"href":"/catalog"
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
第三个问题.添加为属性,嵌入或链接.示例"GET/catalog/food":
{
"_links":{
"self":{
"href":"/catalog/food"
}
},
"name":"food",
"parent":"/catalog",
"categories":[],
"products":[
"/products/burger",
"/products/hot-dog"
]
}
{
"_links":{
"self":{
"href":"/catalog/food"
},
"parent":{
"href":"/catalog"
},
"categories":[
],
"products":[
{
"href":"/products/burger"
}, …Run Code Online (Sandbox Code Playgroud) 我正在试图弄清楚如何建立HAL链接templated: true.如果我使用
BasicLinkBuilder.linkToCurrentMapping().slash("api/public/blogs/{blog}").withRel("blog");
Run Code Online (Sandbox Code Playgroud)
在{和}字符仍然编码.知道如何使用Spring-hateo构建模板URL链接作为0.10.0.RELEASE其API吗?
谢谢.
我正在使用配置了@EnableHypermediaSupport(type = HAL)的Spring Boot和Spring Hateoas.虽然这在基本场景中运行良好,但我希望能够为链接添加其他属性.例如,很容易返回链接,这些链接将呈现如下链接:
{
"_links":{
"self":{
"href":"http://localhost/"
},
"something":[
{
"href":"http://some-url.com/something1"
},
{
"href":"http://some-url.com/something2"
}
]
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是为rel中的对象添加更多属性.例如:
{
"_links":{
"self":{
"href":"http://localhost/"
},
"something":[
{
"name":"something1",
"href":"http://some-url.com/something1"
},
{
"name":"something2",
"href":"http://some-url.com/something2"
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
在不创建自己的DTO的情况下,最好的方法是什么(最好使用ControllerLinkBuilder)?我已经尝试创建自己的Link子类并为name(以及getter和setter)添加字段,但它们似乎被忽略了.
当我为我的实体使用 Spring Data Rest 提供的默认控制器时,一切都会正常工作。输出如下所示:
{
"_links" : {
"search" : {
"href" : "http://localhost:8080/users/search"
}
},
"_embedded" : {
"users" : [ {
"firstName" : "Max",
"lastName" : "Mustermann",
"email" : "mail@max-mustermann.de",
"_links" : {
"self" : {
"href" : "http://localhost:8080/users/myadmin"
}
}
} ]
}
}
Run Code Online (Sandbox Code Playgroud)
但如果我使用自己的控制器,输出将如下所示:
[ {
"firstName" : "Max",
"lastName" : "Mustermann",
"email" : "mail@max-mustermann.de",
"links" : [ {
"rel" : "self",
"href" : "http://localhost:8080/user/myadmin"
} ]
} ]
Run Code Online (Sandbox Code Playgroud)
我的控制器
@RestController
@RequestMapping("/user")
@EnableHypermediaSupport(type = {HypermediaType.HAL}) …Run Code Online (Sandbox Code Playgroud) 我想默认禁用 HAL 格式。
流文档,我设置了这个属性。
spring.hateoas.use-hal-as-default-json-media-type=false
Run Code Online (Sandbox Code Playgroud)
然后测试一下:
1. 带 header 的请求Accept: application/json。
标题:Content-Type: application/json;charset=UTF-8
回复:
{
"links": {}
}
Run Code Online (Sandbox Code Playgroud)
2. 带标头Accept: */*或不带Accept标头的请求。
标题:Content-Type: application/hal+json;charset=UTF-8
回复:
{
"_embedded": {},
"_links": {}
}
Run Code Online (Sandbox Code Playgroud)
版本spring-boot是1.5.3,我用的是spring-boot-starter-hateoas.
无论如何,在没有指定 header 的情况下,是否让 hatoas 在没有 HAL 的情况下响应 json?
多谢。
更新:
请求地址:http://localhost:8080/greeting
带有 header 的请求Accept: */*。
HTTP/1.1 200
Content-Type: application/hal+json;charset=UTF-8
{
"content":"Hello, World!",
"_links":{
"self":{
"href":"http://localhost:8080/greeting?name=World"
}
}
}
Run Code Online (Sandbox Code Playgroud)
带有 header 的请求 …
暂时忽略3xx响应,我想知道为什么HTTP位置标头仅与POST请求/ 201(创建)响应一起使用.
来自RFC 2616规范:
对于201(已创建)响应,Location是请求创建的新资源的位置.
这是一种受到广泛支持的行为,但为什么不应该将其与其他HTTP方法一起使用?以JSON API规范为例:
它为JSON有效负载内的当前资源定义了一个自引用链接(对于RESTful API来说并不罕见).此链接包含在每个有效负载中.该规范说,你必须包括HTTP标头的位置,如果你创建通过POST,且这个值是一样的,在有效载荷自参考链接一个新的文件,但是这仅需要POST.如果您可以使用HTTP位置标头,为什么还要使用自引用链接的自定义格式?
注意:这不是特定于JSON API的.这是对同一HAL,JSON的Hyper-模式或其他标准.
注意2:它甚至不是特定于HTTP位置标头,因为它与HTTP链接标头相同.正如您所看到的,JSON API,HAL和JSON Hyper-Schema不仅定义了自引用链接的约定,还表达了有关资源的相关资源或可能的操作的信息.但似乎他们都可以使用HTTP链接头.(如果他们不想使用HTTP位置标头,他们甚至可以将自引用链接放入HTTP链接头.)
我不想咆哮,它似乎只是某种"重新发明轮子".它似乎也是非常有限的:如果你只是使用HTTP位置/链接头,那么你在HTTP接受头中询问JSON,XML或其他什么并不重要,你会获得关于你的资源的有用的元信息HEAD请求,如果您使用JSON API,HAL或JSON Hyper-Schema,则不包含链接.
hal-json ×10
hateoas ×5
json ×5
rest ×4
java ×2
spring ×2
api ×1
curie ×1
download ×1
entry-point ×1
inline ×1
json-api ×1
spring-boot ×1
spring-mvc ×1