<div>
<a class="article-series-header" href="javascript:void(0);">該文章是系列中的一部分</a>
<div>
<div>
<div>
• 介紹 RAML – RESTful API 建模語言 (當前文章)
</div>
• 使用資源類型和特性的 RAML 中消除冗餘
<br>
• 使用包含、庫、覆蓋和擴展進行模塊化 RAML
<br>
• 使用註釋定義自定義 RAML 屬性
<br>
</div>
<!-- end of article series inner -->
</div>
<!-- .article-series-links -->
</div>
<!-- end of article-series section -->
1. 概述
本文介紹 RESTful API 建模語言 (RAML),這是一種中立的、開放規範語言,基於 YAML 1.2 和 JSON,用於描述 RESTful API。
我們將涵蓋基本的 RAML 1.0 語法和文件結構,並通過演示如何定義一個簡單的基於 JSON 的 API 來展示。 此外,我們還將展示如何通過使用 includes 來簡化 RAML 文件維護。 如果您有使用 JSON 模式的遺留 API,我們將展示如何將模式集成到 RAML 中。
然後,我們將介紹一些可以增強您進入 RAML 旅程的工具,包括作者工具、文檔生成器和其他工具。
最後,我們將總結 RAML 規範的當前狀態。
2. 定義你的API (創建.raml文件)
我們將要定義的API相當簡單:給定實體類型Foo,定義基本的CRUD操作和一些查詢操作。以下是我們為API定義的資源:
- GET /api/v1/foos
- POST /api/v1/foos
- GET /api/v1/foos/{id}
- PUT /api/v1/foos/{id}
- DELETE /api/v1/foos/{id}
- GET /api/v1/foos/name/{name}
- GET /api/v1/foos?name={name}&ownerName={ownerName}
我們還將定義API為無狀態,使用HTTP Basic認證,並以加密方式通過HTTPS傳遞。最後,我們選擇JSON作為數據傳輸格式(XML也受支持)。
2.1. 根級別設置
我們將首先創建一個簡單的文本文件,命名為 api.raml (建議使用 .raml 前綴,名稱可以自定義)。 在文件的根級別,我們將添加 RAML 版本頭信息到第一行。 根級別定義了應用於整個 API 的設置:
#%RAML 1.0
title: Baeldung Foo REST Services API using Data Types
version: v1
protocols: [ HTTPS ]
baseUri: http://myapi.mysite.com/api/{version}
mediaType: application/json
請注意第3行使用了花括號 { } 包圍“version”這個詞。 這告訴 RAML,“version”指的是一個屬性,並且需要進行展開。 因此實際的 baseUri 將是: http://myapi.mysite.com/v1
[注意:version 屬性是可選的,並且不需要作為 baseUri 的一部分。]
2.2. 安全性
安全性也定義在 .raml 文件根級別。 讓我們添加我們的 HTTP 基本安全方案定義:
securitySchemes:
basicAuth:
description: Each request must contain the headers necessary for
basic authentication
type: Basic Authentication
describedBy:
headers:
Authorization:
description: Used to send the Base64-encoded "username:password"
credentials
type: string
responses:
401:
description: |
Unauthorized. Either the provided username and password
combination is invalid, or the user is not allowed to access
the content provided by the requested URL.2.3 數據類型
接下來,我們將定義 API 將使用的各種數據類型:
types:
Foo:
type: object
properties:
id:
required: true
type: integer
name:
required: true
type: string
ownerName:
required: false
type: string上面示例使用了擴展的語法來定義我們的數據類型。RAML 提供了一些語法捷徑,以使類型定義更簡潔。以下是使用這些捷徑的等效數據類型部分:
types:
Foo:
properties:
id: integer
name: string
ownerName?: string
Error:
properties:
code: integer
message: string後跟屬性名稱的 ‘?’ 字符表示該屬性是可選的。
2.4. 資源
現在,我們將定義我們 API 的頂層資源(URI):
/foos:2.5. URI 參數
接下來,我們將擴展資源列表,從我們的頂級資源開始:
/foos:
/{id}:
/name/{name}:
在這裏,URI參數周圍的大括號 { } 定義了屬性名稱。它們是每個URI中的佔位符,並不引用根級別的RAML文件屬性,就像我們在上文的 baseUri 聲明中所看到的。添加的行代表資源 /foos/{id} 和 /foos/name/{name}。
2.6. 方法
接下來,需要定義應用於每個資源的 HTTP 方法:
/foos:
get:
post:
/{id}:
get:
put:
delete:
/name/{name}:
get:2.7. 查詢參數
現在我們將定義使用查詢參數查詢 foos 集合的方法。請注意,查詢參數使用與我們之前為數據類型所使用相同的語法:
/foos:
get:
description: List all Foos matching query criteria, if provided;
otherwise list all Foos
queryParameters:
name?: string
ownerName?: string2.8. 響應
現在我們已經定義了 API 的所有資源,包括 URI 參數、HTTP 方法和查詢參數,接下來需要定義預期的響應和狀態碼。響應格式通常會根據數據類型和示例進行定義。
JSON 模式可以用於與早期版本的 RAML 保持向後兼容,我們將會在第 3 節中介紹 JSON 模式。
[注意:在下面的代碼片段中,僅包含三個點 (…) 的行表示為了簡潔,省略了部分行。]
讓我們從簡單的 GET 操作在 /foos/{id}/ 開始:
/foos:
...
/{id}:
get:
description: Get a Foo by id
responses:
200:
body:
application/json:
type: Foo
example: { "id" : 1, "name" : "First Foo" }
此示例展示了通過對資源 /foos/{id} 執行 GET 請求,我們應該返回匹配的 Foo 對象,格式為 JSON 對象,並返回 HTTP 狀態碼 200。
以下是如何定義對 /foos 資源的 GET 請求:
/foos:
get:
description: List all Foos matching query criteria, if provided;
otherwise list all Foos
queryParameters:
name?: string
ownerName?: string
responses:
200:
body:
application/json:
type: Foo[]
example: |
[
{ "id" : 1, "name" : "First Foo" },
{ "id" : 2, "name" : "Second Foo" }
]
請注意,Foo 類型後會使用方括號 [] 進行追加。這演示了我們如何定義包含Foo 對象數組的響應主體,示例是一個 JSON 對象數組。
2.9. 請求體
接下來,我們將定義與每個 POST 和 PUT 請求相對應的請求體。我們先創建一個新的 Foo 對象:
/foos:
...
post:
description: Create a new Foo
body:
application/json:
type: Foo
example: { "id" : 5, "name" : "Another foo" }
responses:
201:
body:
application/json:
type: Foo
example: { "id" : 5, "name" : "Another foo" }
2.10. 狀態碼
請注意在創建新對象時,我們返回的 HTTP 狀態碼為 201。 PUT 操作用於更新對象將返回 HTTP 狀態碼 200,並使用與 POST 操作相同的請求和響應體。
除了在請求成功時預期的響應和狀態碼外,我們還可以定義在發生錯誤時預期的響應類型和狀態碼。
讓我們看看如何定義在 GET 請求針對 foos/{id}</em/> 資源時,當未找到具有給定 ID 的資源時,預期的響應:
404:
body:
application/json:
type: Error
example: { "message" : "Not found", "code" : 1001 }
3. 使用 JSON Schema 定義 RAML
在 RAML 1.0 中引入 數據類型 之前,對象、請求體和響應體都使用 JSON Schema 進行定義。
雖然使用 數據類型 非常強大,但在某些情況下你仍然可能需要使用 JSON Schema。在 RAML 0.8 中,你使用根級別的 schemas 部分來定義你的 schema。
這仍然有效,但建議使用 types 部分,因為在未來的版本中,使用 schemas 可能會被棄用。 types、schemas、type 和 schema 都是同義詞。
下面是如何在 .raml 文件的根級別使用 JSON schema 定義 Foo 對象類型的示例:
types:
foo: |
{ "$schema": "http://json-schema.org/schema",
"type": "object",
"description": "Foo details",
"properties": {
"id": { "type": integer },
"name": { "type": "string" },
"ownerName": { "type": "string" }
},
"required": [ "id", "name" ]
}以下是翻譯後的內容:
以下是如何在 GET /foos/{id} 資源定義中引用模式:
/foos:
...
/{id}:
get:
description: Get a Foo by its id
responses:
200:
body:
application/json:
type: foo
...4. 使用包含機制進行重構
如前文所述,我們的API變得越來越冗餘和重複。
RAML規範提供了包含機制,允許我們將重複且冗長的代碼片段外部化。
我們可以使用包含機制重構我們的API定義,使其更簡潔,並降低因“複製粘貼/在所有地方修復”方法導致的錯誤機率。
例如,我們可以將Foo對象的數據類型放在types/Foo.raml文件中,將Error對象的數據類型放在types/Error.raml文件中。 那麼我們的types部分將如下所示:
types:
Foo: !include types/Foo.raml
Error: !include types/Error.raml如果使用 JSON 模式,我們的 類型 部分可能如下所示:
types:
foo: !include schemas/foo.json
error: !include schemas/error.json5. 完成 API
在將所有數據類型和示例外部化到其文件後,我們可以使用 include 功能來重構我們的 API:
#%RAML 1.0
title: Baeldung Foo REST Services API
version: v1
protocols: [ HTTPS ]
baseUri: http://rest-api.baeldung.com/api/{version}
mediaType: application/json
securedBy: basicAuth
securitySchemes:
basicAuth:
description: Each request must contain the headers necessary for
basic authentication
type: Basic Authentication
describedBy:
headers:
Authorization:
description: Used to send the Base64 encoded "username:password"
credentials
type: string
responses:
401:
description: |
Unauthorized. Either the provided username and password
combination is invalid, or the user is not allowed to access
the content provided by the requested URL.
types:
Foo: !include types/Foo.raml
Error: !include types/Error.raml
/foos:
get:
description: List all Foos matching query criteria, if provided;
otherwise list all Foos
queryParameters:
name?: string
ownerName?: string
responses:
200:
body:
application/json:
type: Foo[]
example: !include examples/Foos.json
post:
description: Create a new Foo
body:
application/json:
type: Foo
example: !include examples/Foo.json
responses:
201:
body:
application/json:
type: Foo
example: !include examples/Foo.json
/{id}:
get:
description: Get a Foo by id
responses:
200:
body:
application/json:
type: Foo
example: !include examples/Foo.json
404:
body:
application/json:
type: Error
example: !include examples/Error.json
put:
description: Update a Foo by id
body:
application/json:
type: Foo
example: !include examples/Foo.json
responses:
200:
body:
application/json:
type: Foo
example: !include examples/Foo.json
404:
body:
application/json:
type: Error
example: !include examples/Error.json
delete:
description: Delete a Foo by id
responses:
204:
404:
body:
application/json:
type: Error
example: !include examples/Error.json
/name/{name}:
get:
description: List all Foos with a certain name
responses:
200:
body:
application/json:
type: Foo[]
example: !include examples/Foos.json
6. RAML 工具
RAML 的一大優勢在於其強大的工具支持。
有用於解析、驗證和編寫 RAML API 的工具;有用於生成客户端代碼的工具;有用於生成 HTML 和 PDF 格式的 API 文檔工具;以及有幫助我們使用 RAML API 規範進行測試的工具。
甚至還有一個工具可以將 Swagger JSON API 轉換為 RAML。
以下是一些可用的工具示例:
- API Designer – 一個面向快速高效 API 設計的基於 Web 的工具
- API Workbench – 一個用於設計、構建、測試和文檔化 RESTful API 的 IDE,支持 RAML 0.8 和 1.0
- RAML Cop – 一個用於驗證 RAML 文件的工具
- RAML for JAX-RS – 一組工具,用於從 RAML 規範生成 Java + JAX-RS 應用程序代碼的骨架,或從現有的 JAX-RS 應用程序生成 RAML 規範
- RAML Sublime Plugin – Sublime text 編輯器中的語法高亮插件
- RAML to HTML – 一個用於從 RAML 生成 HTML 文檔的工具
- raml2pdf – 一個用於從 RAML 生成 PDF 文檔的工具
- RAML2Wiki – 一個用於生成 Wiki 文檔(使用 Confluence/JIRA 標記)的工具
- SoapUI RAML Plugin – 一個 RAML 插件,用於流行的 SoapUI 功能 API 測試套件
- Vigia – 一個集成測試套件,能夠基於 RAML 定義生成測試用例
要查看 RAML 工具和相關項目的完整列表,請訪問 RAML 項目 頁面。
7. 當前 RAML 狀態
RAML 1.0 (RC) 規範於 2015 年 11 月 3 日獲得發佈候選狀態,在此撰寫時,預計 1.0 版本將在本月完成最終定稿。其前身 RAML 0.8 於 2014 年秋季首次發佈,並且仍然得到眾多工具的支持。
8. 進一步閲讀
以下是一些在學習 RAML 過程中可能對我們有用的鏈接:
- RAML.org – RAML 規範的官方網站
- json-schema.org – JSON 模式的家園
- Understanding JSON Schema – 瞭解 JSON 模式
- 維基百科 RAML 頁面 – RAML (軟件) 頁面
9. 結論
本文介紹了 RESTful API 建模語言 (RAML)。我們演示了使用 RAML 1.0 (RC) 規範編寫簡單 API 規範的基本語法。
我們還看到了通過使用語法捷徑和將數據類型、模式以及示例外部化來使定義更簡潔的方法。
然後,我們介紹了可以與 RAML 規範一起使用,以協助日常 API 設計、開發、測試和文檔任務的一系列強大工具。
隨着規範 1.0 正式發佈的預期,以及開發人員對工具的廣泛支持,RAML 似乎已經確立了其地位。