带有表单和链接的JSON Hypermedia Api

时间:2012-11-24 14:52:36

标签: json forms rest hateoas hypermedia

我正处于规划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

顺便说一句真好的话题!

赞赏所有输入!

5 个答案:

答案 0 :(得分:7)

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

1)

我觉得链接关系应该只是GET,因为在HTML中它们用于包括样式表之类的东西。我猜其他人也有同感,因为IANA链接关系有edit-formcreate-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只是一个粗粒度的解决方案......

  • 例如JSON-LD Hydra和自定义词汇:

    {
        "@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。

如果您决定自己写一个,请创建一个邮件列表并邀请其他人参与。如果你不这样做,你就有可能过于紧密地定制它以满足你自己的需要,并且不小心忽略了一些阻止它被广泛应用的要求。