知識庫 / REST RSS 訂閱

RAML 入門 – RESTful API 建模語言

REST
HongKong
4
03:59 AM · Dec 06 ,2025
<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?: string

2.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 可能會被棄用。 typesschemastypeschema 都是同義詞。

下面是如何在 .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.json

5. 完成 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 過程中可能對我們有用的鏈接:

9. 結論

本文介紹了 RESTful API 建模語言 (RAML)。我們演示了使用 RAML 1.0 (RC) 規範編寫簡單 API 規範的基本語法。

我們還看到了通過使用語法捷徑和將數據類型、模式以及示例外部化來使定義更簡潔的方法。

然後,我們介紹了可以與 RAML 規範一起使用,以協助日常 API 設計、開發、測試和文檔任務的一系列強大工具。

隨着規範 1.0 正式發佈的預期,以及開發人員對工具的廣泛支持,RAML 似乎已經確立了其地位。

下一頁 »
使用資源類型和特性消除 RAML 中的冗餘
user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.