本节详细介绍了基于 Spring Data REST 的应用程序提供的各种形式的元数据。Spring中文文档

应用程序级配置文件语义 (ALPS)

ALPS 是一种数据格式,用于定义应用程序级语义的简单描述,其复杂程度类似于 HTML 微格式。ALPS 文档可以用作配置文件,以解释具有与应用程序无关的媒体类型(例如 HTML、HAL、Collection+JSON、Siren 等)的文档的应用程序语义。这增加了配置文件文档在跨媒体类型的可重用性。
— M.阿德蒙森 / L.理查森 / M.福斯特
https://tools.ietf.org/html/draft-amundsen-richardson-foster-alps-00

Spring Data REST为每个导出的存储库提供了一个ALPS文档。它包含有关两个 RESTful 转换的信息 以及每个存储库的属性。Spring中文文档

Spring Data REST 应用程序的根目录是一个配置文件链接。假设您有一个同时具有 和 related 的应用程序,根目录 文档如下:personsaddressesSpring中文文档

{
  "_links" : {
    "persons" : {
      "href" : "http://localhost:8080/persons"
    },
    "addresses" : {
      "href" : "http://localhost:8080/addresses"
    },
    "profile" : {
      "href" : "http://localhost:8080/profile"
    }
  }
}

RFC 6906 中定义的配置文件链接是包含应用程序级详细信息的位置。ALPS草案规范旨在定义特定的配置文件格式, 我们将在本节后面探讨。Spring中文文档

如果导航到 的配置文件链接,则会看到类似于以下内容的内容:localhost:8080/profileSpring中文文档

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/profile"
    },
    "persons" : {
      "href" : "http://localhost:8080/profile/persons"
    },
    "addresses" : {
      "href" : "http://localhost:8080/profile/addresses"
    }
  }
}
在根级别,是单个链接,不能提供多个应用程序配置文件。那 是您必须导航到以查找每个资源元数据的链接的原因。profile/profile

如果导航到并查看资源的配置文件数据,则会看到类似于以下示例的内容:/profile/personsPersonSpring中文文档

{
  "version" : "1.0",
  "descriptors" : [ {
    "id" : "person-representation", (1)
    "descriptors" : [ {
      "name" : "firstName",
      "type" : "SEMANTIC"
    }, {
      "name" : "lastName",
      "type" : "SEMANTIC"
    }, {
      "name" : "id",
      "type" : "SEMANTIC"
    }, {
      "name" : "address",
      "type" : "SAFE",
      "rt" : "http://localhost:8080/profile/addresses#address"
    } ]
  }, {
    "id" : "create-persons", (2)
    "name" : "persons", (3)
    "type" : "UNSAFE", (4)
    "rt" : "#person-representation" (5)
  }, {
    "id" : "get-persons",
    "name" : "persons",
    "type" : "SAFE",
    "rt" : "#person-representation"
  }, {
    "id" : "delete-person",
    "name" : "person",
    "type" : "IDEMPOTENT",
    "rt" : "#person-representation"
  }, {
    "id" : "patch-person",
    "name" : "person",
    "type" : "UNSAFE",
    "rt" : "#person-representation"
  }, {
    "id" : "update-person",
    "name" : "person",
    "type" : "IDEMPOTENT",
    "rt" : "#person-representation"
  }, {
    "id" : "get-person",
    "name" : "person",
    "type" : "SAFE",
    "rt" : "#person-representation"
  } ]
}
1 资源属性的详细列表(标识为 )列出了名称 的属性。Person#person-representation
2 支持的操作。这说明如何创建一个新的 .Person
3 is ,它表示(因为它是复数)POST 应该应用于整个集合,而不是单个 .namepersonsperson
4 是 ,因为此操作可以更改系统的状态。typeUNSAFE
5 是 ,表示返回的资源类型将为 resource。rt#person-representationPerson
此 JSON 文档的媒体类型为 。这与之前的 JSON 文档不同,后者具有 媒体类型为 .这些格式是不同的,并受不同规格的约束。application/alps+jsonapplication/hal+json

您还可以在检查集合资源时在集合中找到链接,如以下示例所示:profile_linksSpring中文文档

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons" (1)
    },
    ... other links ...
    "profile" : {
      "href" : "http://localhost:8080/profile/persons" (2)
    }
  },
  ...
}
1 此 HAL 文档表示集合。Person
2 它具有指向元数据的相同 URI 的配置文件链接。

同样,默认情况下,该链接提供 ALPS。但是,如果使用 Accept 标头,则可以提供 .profileapplication/alps+jsonSpring中文文档

超媒体控件类型

ALPS 显示每个超媒体控件的类型。它们包括:Spring中文文档

表 1.ALPS类型
类型 描述

语义Spring中文文档

状态元素(如 、 等)。HTML.SPANHTML.INPUTSpring中文文档

安全Spring中文文档

触发安全、幂等状态转换(如 或 )的超媒体控件。GETHEADSpring中文文档

幂等Spring中文文档

触发不安全的幂等状态转换(如 或 )的超媒体控件。PUTDELETESpring中文文档

不安全的Spring中文文档

触发不安全、非幂等状态转换(如 )的超媒体控件。POSTSpring中文文档

在前面所示的表示部分中,来自应用程序的数据位被标记为 。该领域 是涉及要检索的保险箱的链接。因此,它被标记为 .超媒体操作本身映射到类型上,如下 如上表所示。SEMANTICaddressGETSAFESpring中文文档

带投影的ALPS

如果定义任何投影,它们也会列在 ALPS 元数据中。假设我们还定义了 和 ,它们 将出现在相关操作中。(有关这两种预测的定义和讨论,请参阅“预测”。也就是说,GET 将出现在整个集合的操作中,而 GET 将出现在单个资源的操作中。以下示例显示 该小节的替代版本:inlineAddressnoAddressesget-personsSpring中文文档

...
  {
    "id" : "get-persons",
    "name" : "persons",
    "type" : "SAFE",
    "rt" : "#person-representation",
    "descriptors" : [ { (1)
      "name" : "projection",
      "doc" : {
        "value" : "The projection that shall be applied when rendering the response. Acceptable values available in nested descriptors.",
        "format" : "TEXT"
      },
      "type" : "SEMANTIC",
      "descriptors" : [ {
        "name" : "inlineAddress", (2)
        "type" : "SEMANTIC",
        "descriptors" : [ {
          "name" : "address",
          "type" : "SEMANTIC"
        }, {
          "name" : "firstName",
          "type" : "SEMANTIC"
        }, {
          "name" : "lastName",
          "type" : "SEMANTIC"
        } ]
      }, {
        "name" : "noAddresses", (3)
        "type" : "SEMANTIC",
        "descriptors" : [ {
          "name" : "firstName",
          "type" : "SEMANTIC"
        }, {
          "name" : "lastName",
          "type" : "SEMANTIC"
        } ]
      } ]
    } ]
  }
...
1 将出现一个新属性 ,其中包含一个包含一个条目 的数组。descriptorsprojection
2 在里面,我们可以看到。它呈现 、 和 。 在投影中呈现的关系会导致内联包含数据字段。projection.descriptorsinLineAddressaddressfirstNamelastName
3 noAddresses提供包含 和 的子集。firstNamelastName

有了所有这些信息,客户端不仅可以推断出可用的 RESTful 转换,而且在某种程度上可以推断出 与后端交互所需的数据元素。Spring中文文档

在ALPS描述中添加自定义详细信息

您可以创建显示在ALPS元数据中的自定义消息。为此,请按如下方式创建 :rest-messages.propertiesSpring中文文档

rest.description.person=A collection of people
rest.description.person.id=primary key used internally to store a person (not for RESTful usage)
rest.description.person.firstName=Person's first name
rest.description.person.lastName=Person's last name
rest.description.person.address=Person's address

这些属性定义要为资源显示的详细信息。它们更改了 的 ALPS 格式,如下所示:rest.description.*Personperson-representationSpring中文文档

...
  {
    "id" : "person-representation",
    "doc" : {
      "value" : "A collection of people", (1)
      "format" : "TEXT"
    },
    "descriptors" : [ {
      "name" : "firstName",
      "doc" : {
        "value" : "Person's first name", (2)
        "format" : "TEXT"
      },
      "type" : "SEMANTIC"
    }, {
      "name" : "lastName",
      "doc" : {
        "value" : "Person's last name", (3)
        "format" : "TEXT"
      },
      "type" : "SEMANTIC"
    }, {
      "name" : "id",
      "doc" : {
        "value" : "primary key used internally to store a person (not for RESTful usage)", (4)
        "format" : "TEXT"
      },
      "type" : "SEMANTIC"
    }, {
      "name" : "address",
      "doc" : {
        "value" : "Person's address", (5)
        "format" : "TEXT"
      },
      "type" : "SAFE",
      "rt" : "http://localhost:8080/profile/addresses#address"
    } ]
  }
...
1 映射到整个表示中的值。rest.description.person
2 映射到属性的值。rest.description.person.firstNamefirstName
3 映射到属性的值。rest.description.person.lastNamelastName
4 映射到属性的值,通常不显示的字段。rest.description.person.idid
5 映射到属性的值。rest.description.person.addressaddress

提供这些属性设置会导致每个字段都有一个额外的属性。docSpring中文文档

Spring MVC(这是Spring Data REST应用程序的本质)支持语言环境,这意味着您可以捆绑多个 属性文件。
在根级别,是单个链接,不能提供多个应用程序配置文件。那 是您必须导航到以查找每个资源元数据的链接的原因。profile/profile
1 资源属性的详细列表(标识为 )列出了名称 的属性。Person#person-representation
2 支持的操作。这说明如何创建一个新的 .Person
3 is ,它表示(因为它是复数)POST 应该应用于整个集合,而不是单个 .namepersonsperson
4 是 ,因为此操作可以更改系统的状态。typeUNSAFE
5 是 ,表示返回的资源类型将为 resource。rt#person-representationPerson
此 JSON 文档的媒体类型为 。这与之前的 JSON 文档不同,后者具有 媒体类型为 .这些格式是不同的,并受不同规格的约束。application/alps+jsonapplication/hal+json
1 此 HAL 文档表示集合。Person
2 它具有指向元数据的相同 URI 的配置文件链接。
表 1.ALPS类型
类型 描述

语义Spring中文文档

状态元素(如 、 等)。HTML.SPANHTML.INPUTSpring中文文档

安全Spring中文文档

触发安全、幂等状态转换(如 或 )的超媒体控件。GETHEADSpring中文文档

幂等Spring中文文档

触发不安全的幂等状态转换(如 或 )的超媒体控件。PUTDELETESpring中文文档

不安全的Spring中文文档

触发不安全、非幂等状态转换(如 )的超媒体控件。POSTSpring中文文档

1 将出现一个新属性 ,其中包含一个包含一个条目 的数组。descriptorsprojection
2 在里面,我们可以看到。它呈现 、 和 。 在投影中呈现的关系会导致内联包含数据字段。projection.descriptorsinLineAddressaddressfirstNamelastName
3 noAddresses提供包含 和 的子集。firstNamelastName
1 映射到整个表示中的值。rest.description.person
2 映射到属性的值。rest.description.person.firstNamefirstName
3 映射到属性的值。rest.description.person.lastNamelastName
4 映射到属性的值,通常不显示的字段。rest.description.person.idid
5 映射到属性的值。rest.description.person.addressaddress
Spring MVC(这是Spring Data REST应用程序的本质)支持语言环境,这意味着您可以捆绑多个 属性文件。

JSON 架构

JSON Schema 是 Spring Data REST 支持的另一种形式的元数据。 根据他们的网站,JSON Schema 具有以下优点:Spring中文文档

上一部分所示,可以通过从根 URI 导航到链接来访问此数据。profileSpring中文文档

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/profile"
    },
    "persons" : {
      "href" : "http://localhost:8080/profile/persons"
    },
    "addresses" : {
      "href" : "http://localhost:8080/profile/addresses"
    }
  }
}

这些链接与前面显示的相同。若要检索 JSON 架构,可以使用以下标头调用它们:.Acceptapplication/schema+jsonSpring中文文档

在本例中,如果运行 ,则会看到类似于以下内容的输出:curl -H 'Accept:application/schema+json' localhost:8080/profile/personsSpring中文文档

{
  "title" : "org.springframework.data.rest.webmvc.jpa.Person", (1)
  "properties" : { (2)
    "firstName" : {
      "readOnly" : false,
      "type" : "string"
    },
    "lastName" : {
      "readOnly" : false,
      "type" : "string"
    },
    "siblings" : {
      "readOnly" : false,
      "type" : "string",
      "format" : "uri"
    },
    "created" : {
      "readOnly" : false,
      "type" : "string",
      "format" : "date-time"
    },
    "father" : {
      "readOnly" : false,
      "type" : "string",
      "format" : "uri"
    },
    "weight" : {
      "readOnly" : false,
      "type" : "integer"
    },
    "height" : {
      "readOnly" : false,
      "type" : "integer"
    }
  },
  "descriptors" : { },
  "type" : "object",
  "$schema" : "https://json-schema.org/draft-04/schema#"
}
1 导出的类型
2 属性列表

如果您的资源具有指向其他资源的链接,则有更多详细信息。Spring中文文档

您还可以在检查集合资源时在集合中找到链接,如以下示例所示:profile_linksSpring中文文档

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons" (1)
    },
    ... other links ...
    "profile" : {
      "href" : "http://localhost:8080/profile/persons" (2)
    }
  },
  ...
}
1 此 HAL 文档表示集合。Person
2 它具有指向元数据的相同 URI 的配置文件链接。

同样,默认情况下,该链接为 ALPS 提供服务。如果为其提供 的 Accept 标头,则会呈现 JSON 架构表示形式。profileapplication/schema+jsonSpring中文文档

1 导出的类型
2 属性列表
1 此 HAL 文档表示集合。Person
2 它具有指向元数据的相同 URI 的配置文件链接。