20

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

顺便说一句真的很好!

感谢所有输入!

4

5 回答 5

7

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

1.)

我有一种感觉,链接关系应该只是 GET,因为在 HTML 中它们用于包含样式表之类的东西。我想其他人也有同样的感觉,因为存在 anedit-form和 a create-formby IANA 链接关系。

  • 因此,第一个可能的解决方案是取消引用带有表单关系的链接,并下载用于写入操作的表单描述。这些表单描述可以包含 HTML 片段或我们可以用来生成表单的模式。例如

    顺便提一下,您可以通过在标头中发送相同的链接并将原始 JSON 作为正文发送来使用相同的方法。

    {
        "_links": {
            "edit-form": {
                "href": "http://example.com/users/1?form=edit",
                "type": "text/html",
                "title": "Edit user"
            }
        }
    }
    

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

2.)

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

  • 如果我们发送数据,那么我们可以使用type来描述请求体而不是响应体。办公室。在这种情况下,不应该有响应体,否则这个解决方案会令人困惑。

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

  • 例如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 表单的标准,例如,我宁愿使用像解决方案这样的猫鼬模式

        {
            "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
                }
            }
        }
    }
    
于 2014-09-13T00:50:53.810 回答
5

我一直在使用 JSON Hyper Schema 开发 API。您可以四处浏览,甚至可以注册、登录和执行一些操作。在这里查看: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"]
   }
   ]
}
于 2013-12-24T21:45:00.780 回答
5

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

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

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

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

于 2013-01-18T18:17:21.483 回答
4

查看 Collection+JSON、HAL 和/或 Siren。

于 2012-11-24T22:22:17.303 回答
0

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

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

于 2012-12-03T08:22:59.040 回答