具有表单和链接的JSON超媒体应用程序问题如何解决?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (37)

我正处于规划REST API的早期阶段,我希望它遵守REST的HATEOAS约束。但我也想提供一个JSON格式。所以我的问题是,是否有约定代表JSON中的链接和表单。

我找到了链接的例子,看起来这是表示链接的一种非常常见的方式:

"links": [ 
{"rel": "self", "href":"http://example.org/entity/1"},
{"rel": "friends", "href":"http://example.org/entity/1/friends"}] 

另一方面代表形式,并不是我所见过的。我在想,也许有人坐下来思考一些事情,但考虑到了所有的注意事项:

"forms" : [
{"rel" : "new client", "action" : "/clients", "method": "post", 
"fields" : ["name":"string", "zipcode":"int", "signedup":"date", "state": ["Alabama",...]...]}]

这个灵感来自于观看这段视频,Jon Moore建议JSON不适用于超媒体api格式:

http://oredev.org/2010/sessions/hypermedia-apis

提问于
用户回答回答于
用户回答回答于

我已经调查了这个话题了一段时间,但我不确定哪些可能的解决方案可以使用,哪些不可以。只有几个例子可用...所以我需要一些专家的评论...(我的例子将主要在HAL + JSON中。)

1.)

我有一种感觉,即链接关系应该只是GET,因为在HTML中它们是用于包含样式表之类的东西。我想其他人也会有同样的感受,因为IANA edit-formcreate-formIANA之间有一个链接关系。

  • 因此,第一种可能的解决方案是使用表单关系对链接进行解除引用,因此可以下载写入操作的表单描述。这些表单描述可以包含HTML片段或我们可以用来生成表单的模式。例如 只要提到你可以使用相同的方法,通过发送标头中的相同链接并发送原始JSON作为正文。 { "_links": { "edit-form": { "href": "http://example.com/users/1?form=edit", "type": "text/html", "title": "Edit user" } } }

那么,如果链接关系不只是为了阅读目的呢?

2.)

然后我们可以使用HAL的内置功能:

  • 如果我们发送数据,那么我们可以使用type描述请求体而不是响应体。OFC。在这种情况下,不应该有响应机构,否则这个解决方案会令人困惑。 { "_links": { "curies": [ { "name": "my", "href": "http://example.com/rels/{rel}", "templated": true } ], "my:edit": { "href": "http://example.com/users/1", "type": "application/vnd.example.user+json", "title": "Edit user" } } } 所以在这种情况下,客户端会知道这my:edit意味着这是一个编辑表单,并且通过检查MIME类型,它将知道要显示的表单类型。
  • 为了相同目的使用自定义链接关系的替代解决方案: { "_links": { "curies": [ { "name": "my", "href": "http://example.com/rels/{rel}", "templated": true } ], "my:edit-user": { "href": "http://example.com/users/1", "type": "application/json", "title": "Edit user" } } } 因此,通过获取文档,http://example.com/rels/edit-user我们可以找到关于如何构建用于编辑用户的表单的描述,因此我们可以支持my:edit-user客户端中的链接关系。该文档可以包含可选的HTML表单或某种模式,或使用表单描述词汇表等的RDF文档。
  • 我们可以通过profile链接的属性遵循相同的方法。例如: { "_links": { "curies": [ { "name": "my", "href": "http://example.com/rels/{rel}", "templated": true } ], "my:edit": { "href": "http://example.com/users/1", "type": "application/json", "title": "Edit user", "profile": "http://example.com/profiles/user" } } } 所以在这里,链接关系意味着这是一个编辑表单,并profile描述了如何在http://example.com/profiles/userURL 下生成表单。

3.)

或者我们可以使用自定义属性来扩展HAL。

  • 例如,通格式可以做到这一点: { "_forms": { "edit": { "href": "http://example.com/users/1", "headers": { "content-type": "application/json" }, "title": "Edit user", "method": "PUT", "schema": { "required": [ "name" ], "type": "object", "properties": { "name": { "type": "string" } }, "title": "user properties" } } } }
  • 但只要我们没有关于HAL和HAL形式的标准,就可以使用任何其他方法,例如,我宁愿使用猫鼬模式,如解决方案: { "name": "John", "_links": { "curies": [ { "name": "my", "href": "http://example.com/rels/{rel}", "templated": true } ], "my:edit": { "href": "http://example.com/users/1", "type": "application/json", "title": "Edit user", "method": "PUT", "_embedded": { "schema": { "name": "String" } } } } }

4.)

不要使用链接关系和简单的JSON格式,比如HAL,而应该使用带有一个或多个词汇表的RDF。使用RDF比较困难,但它是将客户从REST服务中解耦出来的细粒度解决方案,而HAL只是一个粗粒度解决方案。

  • 例如带有Hydra和自定义词汇的JSON-LD{ "@context": [ "http://www.w3.org/ns/hydra/core", "https://example.com/docs#" ], "@id": "https://example.com/users/1", "name": "John", "operation": { "@type": "ReplaceResourceOperation", "title": "Edit user", "method": "PUT", "expects": { "@id": "https://example.com/docs#User", "supportedProperty": { "@type": "SupportedProperty", "title": "name", "property": "https://example.com/docs#User.name", "range": "http://www.w3.org/2001/XMLSchema#string", "required": true } } } }

扫码关注云+社区