模塊化RAML使用包含、庫、覆蓋和擴展

REST
Remote
1
04:44 PM · Dec 01 ,2025

1. 簡介

在關於 RAML – RESTful API 建模語言的上一兩篇文章中,我們介紹了基本語法,包括數據類型和 JSON 模式的使用,並展示瞭如何通過將常見模式提取到 資源類型特質來簡化 RAML 定義。

在本文中,我們將展示 如何將您的 RAML API 定義分解為模塊,通過使用 包含覆蓋擴展

2. 我們的 API

為了本文的目的,我們將重點關注我們 API 中與名為 Foo 的實體類型的部分。

以下是構成我們 API 的資源:

  • GET /api/v1/foos
  • POST /api/v1/foos
  • GET /api/v1/foos/{fooId}
  • PUT /api/v1/foos/{fooId}
  • DELETE /api/v1/foos/{fooId}

3. Includes

“include” 的作用是模塊化複雜的屬性值,將其放置在外部文件中,從而提高 RAML 規範的模塊化程度。

我們之前的文章簡要介紹了使用“include”時,在指定數據類型和示例,這些示例的屬性值在 API 中被重複使用的情況。

3.1. General Usage and Syntax

“!include” 標籤接受一個參數:包含屬性值的外部文件的位置。該位置可以是絕對 URL、相對於根 RAML 文件的路徑,或相對於包含文件的路徑。

以正斜槓 (/) 開頭的路徑表示相對於根 RAML 文件的路徑,而沒有斜槓開頭的路徑則表示相對於包含文件的路徑。

由此可見,包含的文件可以包含其他“!include” 指令。

以下示例展示了“!include” 標籤的三種用法:

#%RAML 1.0
title: Baeldung Foo REST Services API
...
types: !include /types/allDataTypes.raml
resourceTypes: !include allResourceTypes.raml
traits: !include http://foo.com/docs/allTraits.raml

3.2. Typed Fragments

與其將所有“types”、 “resource types” 或 “traits” 分別放在單獨的“include” 文件中,您還可以使用一種特殊類型的“include”——“typed fragments”,將這些構造體分解為多個“include” 文件,為每個“type”、 “resource type” 或 “trait” 指定不同的文件。

您還可以使用“typed fragments” 來定義 “user documentation items”、 “named examples”、 “annotations”、 “libraries”、 “overlays” 和 “extensions”。 我們稍後會介紹“overlays” 和 “extensions” 的用法。

雖然不是必需的,但“typed fragment” 類型的“include” 文件的第一行可能包含以下格式的 RAML 模塊標識符:

#%RAML 1.0 <fragment-type>

例如,對於“trait” 的“typed fragment” 文件,第一行可能是:

#%RAML 1.0 Trait

如果使用模塊標識符,則文件的內容必須僅包含指定類型的片段的有效 RAML 內容。

讓我們首先看一下 API 中的 “traits” 部分:

traits:
  - hasRequestItem:
      body:
        application/json:
          type: <<typeName>>
  - hasResponseItem:
      responses:
          200:
            body:
              application/json:
                type: <<typeName>>
                example: !include examples/<<typeName>>.json

為了使用“typed fragments” 來模塊化該部分,我們首先將 “traits” 部分重寫如下:

traits:
  - hasRequestItem: !include traits/hasRequestItem.raml
  - hasResponseItem: !include traits/hasResponseItem.raml

然後,我們編寫 “hasRequestItem.raml” 文件:

#%RAML 1.0 Trait
body:
  application/json:
    type: <<typeName>>

“hasResponseItem.raml” 文件的內容如下:

#%RAML 1.0 Trait
responses:
    200:
      body:
        application/json:
          type: <<typeName>>
          example: !include /examples/<<typeName>>.json

4. 庫

RAML 可用於模塊化任意數量和組合的 數據類型安全方案資源類型特性註釋

4.1. 定義一個庫

雖然通常定義在外部文件中,然後作為 包含 引用,但 也可以內聯定義。 包含在外部文件中的 也可以引用其他

與常規 包含類型片段 不同,包含在外部文件中的 必須聲明正在定義的頂級元素名稱。

讓我們將我們的 特性 部分作為 文件重寫:

#%RAML 1.0 Library
# This is the file /libraries/traits.raml
usage: This library defines some basic traits
traits:
  hasRequestItem:
    usage: Use this trait for resources whose request body is a single item
    body:
      application/json:
        type: <<typeName>>
  hasResponseItem:
    usage: Use this trait for resources whose response body is a single item
    responses:
        200:
          body:
            application/json:
              type: <<typeName>>
              example: !include /examples/<<typeName>>.json

4.2. 應用一個庫

通過頂級 使用 屬性應用,其值為一個或多個對象,其屬性名稱是 名稱,其屬性值構成 的內容。

在我們創建了 的內容後,例如 安全方案數據類型資源類型特性,我們可以將 應用到根 RAML 文件:

#%RAML 1.0
title: Baeldung Foo REST Services API
uses:
  mySecuritySchemes: !include libraries/security.raml
  myDataTypes: !include libraries/dataTypes.raml
  myResourceTypes: !include libraries/resourceTypes.raml
  myTraits: !include libraries/traits.raml

4.3. 引用一個庫

通過連接 名稱、一個點 (.), 和要引用的元素的名稱(例如,數據類型、資源類型、特性等)來引用。

正如我們在之前的文章中所回顧的,我們使用 特性 來重構我們的 資源類型。 下面的示例演示瞭如何將“item” 資源類型 作為 ,如何在新的 中包含 特性 (如上所示),以及如何通過前綴 特性 名稱為其 標識符(“myTraits”):

#%RAML 1.0 Library
# This is the file /libraries/resourceTypes.raml
usage: This library defines the resource types for the API
uses:
  myTraits: !include traits.raml
resourceTypes:
  item:
    usage: Use this resourceType to represent any single item
    description: A single <<typeName>>
    get:
      description: Get a <<typeName>> by <<resourcePathName>>
      is: [ myTraits.hasResponseItem, myTraits.hasNotFound ]
    put:
      description: Update a <<typeName>> by <<resourcePathName>>
      is: [ myTraits.hasRequestItem, myTraits.hasResponseItem, myTraits.hasNotFound ]
    delete:
      description: Delete a <<typeName>> by <<resourcePathName>>
      is: [ myTraits.hasNotFound ]
      responses:
        204:

5. Overlays and Extensions

Overlays and extensions are modules defined in external files that are used to extend an API. An overlay is used to extend non-behavioral aspects of an API, such as descriptions, usage directions, and user documentation items, whereas an extension is used to extend or override behavioral aspects of the API.

Unlike includes, which are referenced by other RAML files to be applied as if they were being coded inline, all overlay and extension files must contain a reference (via the top-level masterRef property) to its master file, which can be either a valid RAML API definition or another overlay or extension file, to which they are to be applied.

5.1. Definition

The first line of an overlay or extension file must be formatted as follows:

RAML 1.0 Overlay

And the first line of an overlay file must be formatted similarly:

RAML 1.0 Extension

5.2. Usage Constraints

When using a set of overlays and/or extensions, all of them must refer to the same master RAML file. In addition, RAML processing tools usually expect the root RAML file and all overlay and extension files to have a common file extension (e.g. “.raml”).

5.3. Use Cases for Overlays

The motivation behind overlays is to provide a mechanism for separating interface from implementation, thus allowing the more human-oriented parts of a RAML definition to change or grow more frequently, while the core behavioral aspects of the API remain stable.

A common use case for overlays is to provide user documentation and other descriptive elements in multiple languages. Let’s rewrite the title of our API and add some user documentation items:

#%RAML 1.0
title: API for REST Services used in the RAML tutorials on Baeldung.com
documentation:
  - title: Overview
    content: |
      This document defines the interface for the REST services
      used in the popular RAML Tutorial series at Baeldung.com.
  - title: Copyright
    content: |
      Copyright 2016 by Baeldung.com. All rights reserved.

Here is how we would define a Spanish language overlay for this section:

#%RAML 1.0 Overlay
# File located at (archivo situado en):
# /overlays/es_ES/documentationItems.raml
masterRef: /api.raml
usage: |
  To provide user documentation and other descriptive text in Spanish
  (Para proporcionar la documentación del usuario y otro texto descriptivo
  en español)
title: |
  API para servicios REST utilizados en los tutoriales RAML
  en Baeldung.com
documentation:
  - title: Descripción general
    content: |
      Este documento define la interfaz para los servicios REST
      utilizados en la popular serie de RAML Tutorial en Baeldung.com.
  - title: Derechos de autor
    content: |
      Derechos de autor 2016 por Baeldung.com.
      Todos los derechos reservados.

Another common use case for overlays is to externalize annotation metadata, which essentially are a way of adding non-standard constructs to an API in order to provide hooks for RAML processors such as testing and monitoring tools.

5.4. Use Cases for Extensions

As you may infer from the name, extensions are used to extend an API by adding new behaviors and/or modifying existing behaviors of an API. An analogy from the object-oriented programming world would be a subclass extending a superclass, where the subclass can add new methods and/or override existing methods. An extension may also extend an API’s non-functional aspects.

An extension might be used, for example, to define additional resources that are exposed only to a select set of users, such as administrators or users having been assigned a particular role. An extension could also be used to add features for a newer version of an API.

Below is an extension that overrides the version of our API and adds resources that were unavailable in the previous version:

#%RAML 1.0 Extension
# File located at:
# /extensions/en_US/additionalResources.raml
masterRef: /api.raml
usage: This extension defines additional resources for version 2 of the API.
version: v2
/foos:
  /bar/{barId}:
    get:
      description: |
        Get the foo that is related to the bar having barId = {barId}
      typeName: Foo
      queryParameters:
        barId?: integer
        typeName: Foo
        is: [ hasResponseItem ]

And here is a Spanish-language overlay for that extension:

#%RAML 1.0 Overlay
# Archivo situado en:
# /overlays/es_ES/additionalResources.raml
masterRef: /api.raml
usage: |
  Se trata de un español demasiado que describe los recursos adicionales
  para la versión 2 del API.
version: v2
/foos:
  /bar/{barId}:
    get:
      description: |
        Obtener el foo que se relaciona con el bar tomando barId = {barId}

It is worth noting here that although we used an overlay for the Spanish-language overrides in this example because it does not modify any behaviors of the API, we could just as easily have defined this module to be an extension. And it may be more appropriately defined as an extension, given that its purpose is to override properties found in the English-language extension above it.

6. 結論在本教程中,我們介紹了多種技術,通過將常見構造體分離到外部文件,使 RAML API 定義更具模塊化。

首先,我們展示了 RAML 中 include 功能如何用於將單個、複雜的屬性值重構為可重用外部文件模塊,即 類型片段。 接下來,我們演示瞭如何使用 include 功能將某些元素的集合外部化為可重用的 。 最後,我們通過使用 覆蓋擴展,擴展了 API 的行為和非行為方面。

要了解更多關於 RAML 模塊化技術的知識,請訪問 RAML 1.0 規範

下一條 »
使用註解定義自定義 RAML 屬性
« 上一篇
使用資源類型和特性的 RAML 中消除冗餘
user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.