REST类型的资源与HYDRA类

REST类型的资源与HYDRA类,rest,api-design,json-ld,hypermedia,hydra-core,Rest,Api Design,Json Ld,Hypermedia,Hydra Core,来自菲尔丁的文章(): RESTAPI永远不应该具有对客户端重要的“类型化”资源。规范作者可以使用资源类型来描述接口后面的服务器实现,但这些类型必须与客户机无关且不可见。对客户机重要的唯一类型是当前表示的媒体类型和标准化关系名称。[同上] 在HYDRA中,可以在API文档中记录类,如下所示: supportedClass: '@id': 'schema:Event' supportedProperty: - property: '@id': event

来自菲尔丁的文章():

RESTAPI永远不应该具有对客户端重要的“类型化”资源。规范作者可以使用资源类型来描述接口后面的服务器实现,但这些类型必须与客户机无关且不可见。对客户机重要的唯一类型是当前表示的媒体类型和标准化关系名称。[同上]

在HYDRA中,可以在API文档中记录类,如下所示:

supportedClass:
  '@id': 'schema:Event'
    supportedProperty:
      - property:
          '@id': eventName
它不被认为是类型化资源吗?JSON-LD中甚至有一个
@type
字段。我理解标准化关系名称的重要性,因为它们为客户端提供了对资源或属性进行有用操作所需的语义、格式和约束,但是通过限制API文档中可能的关系范围,我们实际上是在声明类型(类)

如果没有类,客户机将不知道将出现什么关系,对客户机进行编码以便它知道大多数关系类型(例如,来自schema.org)是不实际的

这个约束的确切含义是什么,它在实践中如何有用?HYDRA不尊重这一点吗


我问这个是出于理论上的兴趣。实际上,如果HTTP API可用,我不在乎它是否满足所有约束。

我认为“类型化资源”(如Fielding所称)与JSON-LD/HYDRA等媒体类型中定义的类型或类之间存在差异。我在回答我自己的问题,但如有必要,请扩展/更正它


TL;DR我的理解是,该约束将类型称为资源的预定义表示(或结构),并主张记录可能的关系和媒体类型处理规则,而不是此结构。这些关系仍然可以分组在“类型”下,但表示形式不会僵化


属性通常具有预定义的名称,并可在其封闭类型的上下文中理解。这意味着,为了处理这些类型,服务器/客户机应该同意这种命名约定,并且在一种类型中命名为与在不同类型中命名为相同的字段可能具有完全不同的语义。它产生了一个刚性的资源结构

另一方面,像JSON-LD这样的超媒体类型不以常见的方式使用属性。相反,它们使用一些嵌入信息(@context)来定义属性的语义,这些属性可以是其他实体、值对象、引用等

通过处理具有给定超媒体类型的资源,属性被转换为一些定义良好的关系,通常在词汇表中定义。这意味着相同的关系可以用于多种类型,例如
Person
中的
name
字段和
Book
可以引用它们与值对象(例如简单字符串名称)之间的关系

通过允许客户机使用关系类型的通用词汇表,并定义媒体类型的处理规则,这将使客户机与服务器分离,因此建议在以序列化格式直接使用资源之前对其进行预处理(因为您可能不知道它是如何返回的)

例如:

{
  "@context": "http://schema.org/",
  "@type": "Person",
  "@id": "http://srv.org/users/1",
  "name": "Jane Doe",
  "telephone": "(425) 123-4567",
  "url": "http://www.janedoe.com"
}
资源是否与相同

{
  "@context": {
    "a": "http://schema.org/name",
    "b": "http://schema.org/telephone",
    "c": {
      "@id": "http://schema.org/url",
      "@type": "@id"
    }
  },
  "@type": "http://schema.org/Person",
  "@id": "http://srv.org/users/1",
  "a": "Jane Doe",
  "b": "(425) 123-4567",
  "c": "http://www.janedoe.com"
}
甚至

[
  {
    "@id": "http://srv.org/users/1",
    "@type": [
      "http://schema.org/Person"
    ],
    "http://schema.org/name": [
      {
        "@value": "Jane Doe"
      }
    ],
    "http://schema.org/telephone": [
      {
        "@value": "(425) 123-4567"
      }
    ],
    "http://schema.org/url": [
      {
        "@id": "http://www.janedoe.com"
      }
    ]
  }
]

Jorn Wildt写了一篇很好的关于“谢谢”的博文,请阅读。看来他的理解在某种程度上与我的相似。我认为,从可用性的角度来看,具有不同词汇表的通用媒体类型(JSON-LD和schema.org)或具有特定于域的媒体类型(vCard)是同构的。只有“类型”在其他地方编码。我得说,这归根结底取决于个人的喜好——使用什么。对我来说,如果我编写一个跨越多个域的API,由于统一接口,hydra是首选。如果需要,它以后可以支持特定的介质类型。我将阅读那篇文章中引用的文章。这篇博客文章或Fieldings声明的核心点是,客户不应该从资源的名称推断资源的类型(即
/api/customers
)而是使用内容协商通知服务器,客户机能够处理以下媒体类型,服务器应以客户机理解的表示形式返回信息。Fielding还指出,REST体系结构的重点应该是指定媒体类型和有意义的链接关系名称,而不是过度设计uri。没错,这也是因为uri是透明的,甚至uri结构事先都不知道,所以无论如何也不可能。链接关系应该记录取消引用时URI的范围,我只是想指出,可以通过引用特定媒体类型(vCard)——Jorn Wildt似乎更喜欢这种类型——或者在json ld的情况下,通过引用词汇表(schema.org/CreditCard)中的类型来完成。这是第二个困扰我的例子,因为词汇“type”就是一个type(或者它似乎是第一个,这就是我的答案试图解决的问题)。