【问题标题】:Master-detail representation in Json-LDJson-LD 中的主从表示
【发布时间】:2014-10-10 15:55:53
【问题描述】:

暂且:抱歉,如果我误解了超媒体或 Restfull 概念:这是一项正在进行的工作......)

我尝试弄清楚超媒体和 hydra (http://www.markus-lanthaler.com/hydra),并且在设计我的 api 之前有一些关于向客户端返回信息的问题。

假设我有一个位于 www.myshop.com 的网上商店

到根的 HTTP GET 可以返回(例如)表示为链接的资源列表(在 json-ld 文档中):

...
"@id": "/api",
"products" : "www.myshop.com/api/products",
"customers":"www.myshop.com/api/customers"
...

第一个问题关于 hydra,我如何在此处添加操作?似乎客户端需要在加载应用程序之前加载另一个文档。我的意思是潜在的操作不在从 www.myshop.com/api 检索到的文档中或者我错过了什么?


然后更进一步,我已经声明 products 是一个 hydra:Link 以便客户端可以使用 HTTP GET 跟随该链接(与其交互)并检索产品列表。这将是一个这样的列表:

....
{
  "@id": "/api/products/123",
  "@type": "vocab:Product"
},
{
  "@id": "/api/products/124",
  "@type": "vocab:Product"
},
....

在这里,客户收到产品列表(可能是分页集合)。但是如果客户想要向用户展示它,假设是一张带有 [product Id, price, name] 的表格(不是所有 Product 的属性)

第二个问题:如果没有客户端向服务器发送每个产品的请求,但仍然提供链接以获取产品的详细信息,我怎么能做到这一点,(甚至这里有四个链接:一个用于获取详细信息,一个用于删除,一个用于与朋友分享,最后一个用于将其添加到购物篮)?

事实上,如果文档本身没有链接,我很难弄清楚 hydra 是如何发挥作用的?我认为 Hal 使用这种方法在文档本身中添加链接(如果我是对的),我试图找出 hydra 是如何做这个链接的......

问候

【问题讨论】:

    标签: rest restful-architecture json-ld hypermedia hydra-core


    【解决方案1】:

    注意:我不太确定答案的 Hydra 部分,我认为 JSON-LD 和 REST 还可以。

    您可以通过 JSON-LD 使用@base 和相对 IRI,或者您可以在 @context 中定义命名空间,因此之后您可以使用相对 IRI 作为ns:relativeIRI。每一个都比返回完整的 IRI 要好。 (在客户端使用通用 JSON-LD 解析器比简单的 JSON 解析器更容易解析结果。)

    您可以使用 Hydra 词汇定义自己的 @vocab,也可以在 @context 中添加“动作”定义。如果你想“添加动作”,你必须在你的词汇中使用hydra:Operation 子类。像这样(但我不是 Hydra 专家):

    {
        "@id": "vocab:ProductList",
        //...
        "hydra:supportedOperations": [
            {
                "@type": "hydra:CreateResourceOperation",
                "method": "POST",
                "expects": "vocab:Product"
            }
            //...
        ]
    }
    

    通常,通过 REST,如果您需要具有较少属性的相同资源,则必须为该资源添加新的 IRI,例如:/myresource?fewer=1。例如在您的情况下:/api/products/?fields="id, price, name" 可以。

    如果您想要多个链接,Hydra 有 2 个选择;您可以添加一个新的hydra:Link 作为属性,或者您可以添加一个新的hydra:Operation 作为supportedOperationmethod: GET。我猜 get 操作是针对具有用户输入的搜索之类的,但是如果您不想为每个链接添加新属性,我认为您别无选择。

    实际上 Hydra 确实有链接和操作支持。也许不清楚,但 JSON-LD 是一种 RDF 格式,您可以在其中定义 RDF 三元组。因此,例如 "customers":"www.myshop.com/api/customers" 使用的 IRI 只是资源标识符,而不是链接。一个链接应该有 IRI、标题、方法(GET)、语言、内容类型、iana:relation 等等……所以不可能用一个 IRI(资源标识符)来描述一个你可以跟随的链接。通过处理 REST 资源,客户端永远不应该检查 IRI 结构以了解如何显示它从您那里获得的信息。您必须检查链接的其他属性,尤其是iana:relations 或通过 Hydra 可能的操作类型来执行此操作。因此,例如,在您的情况下,www.myshop.com/api/dav8ufg723udvbquacvd723fudvg 是客户列表中完全有效的 IRI。我们使用漂亮的 IRI 只是因为在服务器端配置生成它们并为它们配置路由器更容易。

    在进一步的问题之前,请检查Hydra vocab。如您所见,Class 可以有supportedOperationssupportedProperties,它们都是集合。 LinkProperty 的子类,它可以有一个 Operation。通过集合,我认为您必须使用 Collection 类,其中 member 包含集合的项目...请注意,通过 JSON-LD 定义单个项目或多个项目没有区别类型。在上下文中,您必须只定义类型,并且属性的值可以包含单个项目或项目数组......如果你想要一些约束,我想你必须添加一些 OWL 三元组和一个使用它们检查值的验证器。

    【讨论】:

    • 在回来之前,我会检查 rdf 规范,因为这一切对我来说都是新的。我还有一些问题,但会先检查 rdf。
    • 这并不难,你有subject ----<predicate>-----> target 三元组。例如I have a child = example.com/me/children/count, example.com/logical/equalsTo, 1。几乎可以用这种方式描述一切……REST 使用类似的概念,它用 REST 资源描述一切。对于 JSON-LD,这些也是 RDF 资源,因为 JSON-LD 是一种 RDF 文件格式,而 REST 资源具有资源 ID (IRI),因此它们可以是三元组的任何部分。比如user.id = 1 = example.com/user/1 example.com/vocab/User/id 1,等等……所以资源可以是文档。
    • 资源的另一部分是“事物”。例如,一个 REST 资源描述了一个真实的人。真人的 IRI 可以是这样的:example.com/user/1#personexample.com/user/1#ppl/inf3rno。如您所见,它指的是由文档描述的非文档。
    • 所以这些是基础,我认为RDF和RDFs词汇你可以自己学习。他们不是那么难......
    【解决方案2】:

    有点晚了,不过我还是会尽力回答你的问题 Cedric。

    假设我有一个位于 www.myshop.com 的网上商店

    到根的 HTTP GET 可以返回(例如)资源列表 表示为链接(在 json-ld 文档中):

     ... "@id": "/api",
     "products" : "www.myshop.com/api/products",
     "customers":"www.myshop.com/api/customers" ...
    

    第一个问题关于 hydra,我如何在此处添加操作?看来 客户端需要在加载应用程序之前加载另一个文档。 我的意思是潜在的行动不在从 www.myshop.com/api 还是我错过了什么?

    您基本上有两种选择:1) 将操作直接嵌入响应中,或者 2) 将操作附加到属性(productscustomers)。

    方法 1) 看起来有点像这样:

    ...
    "@id": "/api",
    "products" : {
      "@id": "http://www.myshop.com/api/products",
      "operation": {
        "@type": "Operation",
        "method": "POST",
        "expects": "Product"
      }
    }
    ...
    

    虽然方法 2) 会将相同的操作附加到引用的 Hydra ApiDocumentation 中的 products 属性:

    ...
    "@id": "...products",
    "supportedOperation": {
      "@type": "Operation",
      "method": "POST",
      "expects": "Product"
    }
    ...
    

    请注意,在 1) 我使用了operation,而在 2) 我使用了supportedOperation。此外,您应该使用比Operation 更具体的类型。

    关于你的第二个问题:

    使用 HTTP GET 并检索产品列表。这将是一个这样的列表:

    ....
    {
      "@id": "/api/products/123",
      "@type": "vocab:Product"
    },
    {
      "@id": "/api/products/124",
      "@type": "vocab:Product"
    },
    ....
    

    这里客户收到一个产品列表(可能是分页的 收藏)。但是如果客户想向用户展示它,让我们 说一个带有 [产品 ID、价格、名称] 的表格(不是所有产品的 属性)

    第二个问题:如果没有客户发送 为每个产品向服务器请求,但仍提供指向 获取产品的详细信息,(甚至这里有四个链接 :一个用于获取详细信息,一个用于删除,一个用于 与朋友和最后一个分享它以将其添加到篮子中)?

    您可以直接在集合中添加任意数量的信息(包括链接)。

    ....
    {
      "@id": "/api/products/123",
      "@type": "vocab:Product",
      "name": "Product 123",
      "price": "9.99"
    },
    {
      "@id": "/api/products/124",
      "@type": "vocab:Product",
      "name": "Product 124",
      "price": "19.99"
    },
    ....
    

    这样,如果集合不包含所需的信息,客户端只需取消对项目的引用。

    事实上,我很难弄清楚 hydra 是如何进入的 通过在文档本身中没有链接来玩吗?

    当然,文档中也有链接。链接只是其值恰好是 URL 的属性(具有 @id 属性的对象,除非您在上下文中将属性的类型设置为 @id 以摆脱它),而不是对它们进行特殊处理。

    【讨论】:

    • 在这部分“请注意,在 1) 我使用了操作,而在 2) 我使用了supportedOperation。此外,您应该使用比 Operation 更具体的类型。”通过更具体的 Operation,您的意思是在所引用的 hydra pai 文档中继承 Operation 的操作?
    • 是的。我的意思是 Operation 的一个子类,它可以告诉您更多关于调用该操作时会发生什么的信息。当前 Hydra 规范中的 CreateResourceOperation 或 schema.org 中的 AddAction 之类的东西
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多