我正处于规划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
顺便说一句真好的话题!
赞赏所有输入!
答案 0 :(得分:7)
我已经研究了这个话题了一段时间,但我不确定ppl使用哪种可能的解决方案,哪些解决方案没有。只有几个例子......所以我需要专家的一些评论......(我的例子主要是HAL + JSON。)
1)
我觉得链接关系应该只是GET,因为在HTML中它们用于包括样式表之类的东西。我猜其他人也有同感,因为IANA链接关系有edit-form
和create-form
。
因此,第一个可能解除引用与表单关系链接的解决方案,因此下载写操作的表单描述。这些表单描述可以包含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/user
URL下生成表单。
3。)
或者我们可以使用自定义属性扩展HAL。
例如dougrain-forms执行此操作:
{
"_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表格的标准,例如我宁愿使用mongoose schema类似的解决方案:
{
"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只是一个粗粒度的解决方案......
{
"@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
}
}
}
}
答案 1 :(得分:5)
查看Collection + JSON,HAL和/或Siren。
答案 2 :(得分:4)
JSON Schema标准(特别是“超级模式”)绝对允许这样做。您引用JSON(超 - )架构(使用HTTP头),架构定义了如何将数据解释为超文本的规则。
构建链接的信息可以在任何地方。超模式记录了如何从数据组装链接URI(它可以是模板),它们还指定HTTP方法,编码类型等。
要获取表单功能:您可以为要提交的数据指定完整架构。必需/可选属性,数组长度约束,等等。
作为演示,这是JavaScript库的演练的一部分,该库可以理解超级模式,并且可以为链接提供适当的表单:jsonary.com。
答案 3 :(得分:4)
我一直在使用JSON Hyper Schema开发API。 您可以浏览aroun,甚至注册,登录和执行某些操作。看看,这里: http://api.psprt.com
[编辑]在这里查看我的最新资料: www.passportedu.com https://github.com/bpanahij/HypermediaServer https://github.com/bpanahij/client-schema.json
我也开源了API代码: https://github.com/bpanahij/passportedu_schema
随意查看,借阅和评论。
JSON Hyper Schema(另请参阅JSON-Schema)有一种指定表单的方法, 通过属性成员:
{
"id": "/api/v1",
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "PassportEDU API",
"name": "PassportEDU API",
"type": "object",
"description": "Bringing global students together with global schools.",
"links": [
{
"title": "Log In",
"rel": "authenticate",
"href": "/api/v1/authenticate",
"method": "POST",
"properties": {
"username": {
"title": "Your username",
"description": "Your email address or username",
"type": "string"
},
"password": {
"title": "Your password",
"description": "Your password",
"type": "password"
}
},
"required": ["username", "password"]
}
]
}
答案 4 :(得分:0)
据我所知,目前还没有公开的通用JSON格式和表格。如果需要,可以自由定义一个并发布规范。作为个人喜好,我建议将其基于HAL。
如果您决定自己写一个,请创建一个邮件列表并邀请其他人参与。如果你不这样做,你就有可能过于紧密地定制它以满足你自己的需要,并且不小心忽略了一些阻止它被广泛应用的要求。