元資料
本節詳細介紹了 Spring Data REST 應用程式提供的各種元資料形式。
應用級配置檔案語義 (ALPS)
ALPS 是一種資料格式,用於定義應用級語義的簡單描述,其複雜性類似於 HTML 微格式。ALPS 文件可以用作配置檔案,以解釋具有應用程式無關媒體型別(如 HTML、HAL、Collection+JSON、Siren 等)的文件的應用程式語義。這增加了配置檔案文件在不同媒體型別之間的可重用性。
https://tools.ietf.org/html/draft-amundsen-richardson-foster-alps-00
Spring Data REST 為每個匯出的儲存庫提供一個 ALPS 文件。它包含有關 RESTful 轉換和每個儲存庫屬性的資訊。
在 Spring Data REST 應用程式的根目錄中有一個配置檔案連結。假設你有一個包含 persons 和相關 addresses 的應用程式,根文件將如下所示:
{
"_links" : {
"persons" : {
"href" : "https://:8080/persons"
},
"addresses" : {
"href" : "https://:8080/addresses"
},
"profile" : {
"href" : "https://:8080/profile"
}
}
}
如果你導航到 localhost:8080/profile 的配置檔案連結,你會看到類似以下內容:
{
"_links" : {
"self" : {
"href" : "https://:8080/profile"
},
"persons" : {
"href" : "https://:8080/profile/persons"
},
"addresses" : {
"href" : "https://:8080/profile/addresses"
}
}
}
在根級別,profile 是一個單一連結,不能提供多個應用程式配置檔案。這就是為什麼你必須導航到 /profile 才能找到每個資源的元資料鏈接。 |
如果你導航到 /profile/persons 並檢視 Person 資源的配置檔案資料,你會看到類似以下示例的內容:
{
"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" : "https://: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 | name 是 persons,這表明(因為它是一個複數)POST 應該應用於整個集合,而不是單個 person。 |
| 4 | type 是 UNSAFE,因為此操作可以更改系統的狀態。 |
| 5 | rt 是 #person-representation,這表示返回的資源型別將是 Person 資源。 |
此 JSON 文件的媒體型別是 application/alps+json。這與之前的 JSON 文件(其媒體型別為 application/hal+json)不同。這些格式不同,並受不同規範的約束。 |
當您檢查集合資源時,您還可以在 _links 集合中找到一個 profile 連結,如下例所示:
{
"_links" : {
"self" : {
"href" : "https://:8080/persons" (1)
},
... other links ...
"profile" : {
"href" : "https://:8080/profile/persons" (2)
}
},
...
}
| 1 | 這個 HAL 文件表示 Person 集合。 |
| 2 | 它有一個指向相同 URI 的 profile 連結用於元資料。 |
同樣,預設情況下,profile 連結提供 ALPS。但是,如果您使用 Accept 頭,它可以提供 application/alps+json。
超媒體控制型別
ALPS 顯示每個超媒體控制元件的型別。它們包括:
| 型別 | 描述 |
|---|---|
語義 |
狀態元素(如 |
安全 |
觸發安全、冪等狀態轉換的超媒體控制元件(如 |
冪等 |
觸發不安全、冪等狀態轉換的超媒體控制元件(如 |
不安全 |
觸發不安全、非冪等狀態轉換的超媒體控制元件(如 |
在前面顯示的表示部分中,來自應用程式的資料位被標記為 SEMANTIC。address 欄位是一個連結,涉及到安全的 GET 來檢索。因此,它被標記為 SAFE。超媒體操作本身對映到如上表所示的型別。
帶有投影的 ALPS
如果您定義了任何投影,它們也會列在 ALPS 元資料中。假設我們還定義了 inlineAddress 和 noAddresses,它們將出現在相關操作中。(有關這兩個投影的定義和討論,請參閱“投影”。)也就是說,GET 將出現在整個集合的操作中,GET 將出現在單個資源的操作中。以下示例顯示了 get-persons 子部分的替代版本:
...
{
"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 | 出現了一個新屬性 descriptors,包含一個只有一個條目 projection 的陣列。 |
| 2 | 在 projection.descriptors 中,我們可以看到 inLineAddress。它渲染 address、firstName 和 lastName。在投影中渲染的關係將資料欄位以內聯方式包含。 |
| 3 | noAddresses 提供了一個包含 firstName 和 lastName 的子集。 |
有了所有這些資訊,客戶端不僅可以推斷可用的 RESTful 轉換,而且在一定程度上也可以推斷與後端互動所需的資料元素。
向 ALPS 描述新增自定義詳細資訊
您可以創建出現在 ALPS 元資料中的自定義訊息。為此,請按如下方式建立 rest-messages.properties:
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
這些 rest.description.* 屬性定義了要為 Person 資源顯示的詳細資訊。它們會修改 person-representation 的 ALPS 格式,如下所示:
...
{
"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" : "https://:8080/profile/addresses#address"
} ]
}
...
| 1 | rest.description.person 的值對映到整個表示。 |
| 2 | rest.description.person.firstName 的值對映到 firstName 屬性。 |
| 3 | rest.description.person.lastName 的值對映到 lastName 屬性。 |
| 4 | rest.description.person.id 的值對映到 id 屬性,一個通常不顯示的欄位。 |
| 5 | rest.description.person.address 的值對映到 address 屬性。 |
提供這些屬性設定會導致每個欄位都有一個額外的 doc 屬性。
| Spring MVC(這是 Spring Data REST 應用程式的精髓)支援區域設定,這意味著您可以將多個屬性檔案與不同的訊息捆綁在一起。 |
JSON Schema
JSON Schema 是 Spring Data REST 支援的另一種元資料形式。根據他們的網站,JSON Schema 具有以下優點:
-
描述您現有資料格式
-
清晰、人機可讀的文件
-
完整的結構驗證,對於自動化測試和驗證客戶端提交的資料非常有用
如上一節所示,您可以透過從根 URI 導航到 profile 連結來獲取此資料。
{
"_links" : {
"self" : {
"href" : "https://:8080/profile"
},
"persons" : {
"href" : "https://:8080/profile/persons"
},
"addresses" : {
"href" : "https://:8080/profile/addresses"
}
}
}
這些連結與前面顯示的相同。要檢索 JSON Schema,您可以使用以下 Accept 頭呼叫它們:application/schema+json。
在這種情況下,如果您執行 curl -H 'Accept:application/schema+json' localhost:8080/profile/persons,您將看到類似以下內容的輸出:
{
"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 | 屬性列表 |
如果您的資源連結到其他資源,則會有更多詳細資訊。
當您檢查集合資源時,您還可以在 _links 集合中找到一個 profile 連結,如下例所示:
{
"_links" : {
"self" : {
"href" : "https://:8080/persons" (1)
},
... other links ...
"profile" : {
"href" : "https://:8080/profile/persons" (2)
}
},
...
}
| 1 | 這個 HAL 文件表示 Person 集合。 |
| 2 | 它有一個指向相同 URI 的 profile 連結用於元資料。 |