带有表单和链接的JSON Hypermedia Api

Jay*_*ete 19 forms rest json 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"}] 
Run Code Online (Sandbox Code Playgroud)

另一方面,代表形式并不是我所见过的.我在想,也许有人坐下来思考这些问题,但考虑了所有的警告:

"forms" : [
{"rel" : "new client", "action" : "/clients", "method": "post", 
"fields" : ["name":"string", "zipcode":"int", "signedup":"date", "state": ["Alabama",...]...]}]
Run Code Online (Sandbox Code Playgroud)

这个灵感来自于观看这个视频,其中Jon Moore认为JSON不是超媒体API的好格式:

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

顺便说一句真好的话题!

所有输入都表示赞赏!

inf*_*rno 7

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

1.)

我觉得链接关系应该只是GET,因为在HTML中它们用于包括样式表之类的东西.我猜其他人也有同感,因为有一个edit-form和一个create-formIANA链接关系.

  • 因此,第一个可能解除引用链接与表单关系的解决方案,因此下载写操作的表单描述.这些表单描述可以包含HTML片段或我们可以用来生成表单的模式.例如

    提一下,你可以通过在标题中发送相同的链接并使用原始JSON作为正文来使用相同的方法.

    {
        "_links": {
            "edit-form": {
                "href": "http://example.com/users/1?form=edit",
                "type": "text/html",
                "title": "Edit user"
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

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

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"
                }
            }
        }
    
    Run Code Online (Sandbox Code Playgroud)

    因此,在这种情况下,客户端将知道这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"
                }
            }
        }
    
    Run Code Online (Sandbox Code Playgroud)

    因此,通过获取文档,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"
                }
            }
        }
    
    Run Code Online (Sandbox Code Playgroud)

    所以在这里,链接关系意味着这是一个编辑表单,并profile描述了如何在http://example.com/profiles/userURL 下生成表单.

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"
                    }
                }
            }
        }
    
    Run Code Online (Sandbox Code Playgroud)
  • 但是你可以使用任何替代方法,只要我们没有关于HAL和HAL表单的标准,例如我宁愿使用类似解决方案的mongoose模式:

        {
            "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"
                        }
                    }
                }
            }
        }
    
    Run Code Online (Sandbox Code Playgroud)

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
                }
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)


小智 5

查看Collection + JSON,HAL和/或Siren.

  • 首先看看HAL:B.5.为什么HAL没有表格?从HAL中省略表单是一项有意的设计决策,旨在使其专注于API的链接.因此,HAL是用作构建更复杂功能的基础媒体类型的良好候选者.计划在未来使用其他媒体类型,这将在HAL之上添加类似于形式的控件.所以这不是真正的候选人......会看其他人. (6认同)
  • 我没有看到任何这些描述形式,所以没有真正回答我的问题. (3认同)
  • Siren有形式,他们只称它为"行动".它支持大多数(如果不是全部)HTML 5中定义的控件类型. (2认同)

clo*_*eet 5

JSON架构标准(特别是“超模式”),明确允许这样做。您引用了 JSON (Hyper-)Schema(使用 HTTP 标头),并且该架构定义了有关如何将数据解释为超文本的规则。

用于构建链接的信息可以在任何地方。超模式记录了如何从数据中组装链接 URI(它可以是模板),并且它们还指定了 HTTP 方法、编码类型等。

要获得表单功能:您可以为要与请求一起提交的数据指定完整的架构。必需/可选属性、数组长度约束等。

作为演示,这里是 JavaScript 库演练的一部分,该库了解超模式并可以为链接提供适当的形式:jsonary.com


Bri*_*son 5

我一直在研究 API,使用 JSON Hyper Schema。您可以四处浏览,甚至可以注册、登录并执行一些操作。在这里查看: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"]
   }
   ]
}
Run Code Online (Sandbox Code Playgroud)


Nic*_*nks 0

据我所知,目前还没有公开指定的通用 JSON 格式的表单。如果需要,您可以自由定义并发布规范。作为个人喜好,我建议基于 HAL。

如果您决定自己编写一个邮件列表,请创建一个邮件列表并邀请其他人参与。如果不这样做,您可能会面临对其进行过于严格的定制以满足您自己的需求的危险,并且会意外地忽略一些阻止其广泛应用的要求。