1. 简介

本文是 RAML(RESTful API Modeling Language)系列教程的第四篇,主要介绍 **如何通过 注解(annotations)为 RAML API 规范定义自定义属性**。这个过程也称为对规范元数据的扩展。

注解可以为 RAML 处理工具提供额外的扩展信息,这些信息超出了 RAML 官方语言本身的定义范围。

2. 声明注解类型

我们可以通过顶层的 annotationTypes 属性来声明一个或多个 注解类型

最简单的情况下,只需要指定 注解类型名称,此时它的值类型默认为字符串:

annotationTypes:
  simpleImplicitStringValueType:

这等价于显式声明如下:

annotationTypes:
  simpleExplicitStringValueType:
    type: string

在更复杂的情况下,注解类型可以包含一个值对象,也就是所谓的 注解类型声明

此时,注解类型使用与 数据类型 相同的语法定义,并支持两个可选属性:

  • allowedTargets:指定注解可以应用的目标位置类型,值为字符串或字符串数组。
  • allowMultiple:布尔值,表示是否允许在同一个目标位置多次使用该注解,默认为 false

下面是一个包含多个属性和配置的注解类型示例:

annotationTypes:
  complexValueType:
    allowMultiple: true
    properties:
      prop1: integer
      prop2: string
      prop3: boolean

2.1. 支持注解的目标位置

注解可以应用在多个根级别的目标位置上,包括:

  • API 根级别
  • 资源类型(resource types)
  • 特性(traits)
  • 数据类型(data types)
  • 文档项(documentation items)
  • 安全方案(security schemes)
  • 库(libraries)
  • 覆盖(overlays)
  • 扩展(extensions)
  • 其他注解类型

此外,注解也可以用于:

  • 安全方案设置(security scheme settings)
  • 资源(resources)
  • 方法(methods)
  • 响应声明(responses)
  • 请求体(request bodies)
  • 响应体(response bodies)
  • 命名示例(named examples)

2.2. 限制注解类型的目标位置

如果要限制某个注解类型只能用于特定的目标位置,可以设置 allowedTargets 属性。

当只允许一个目标类型时,使用字符串:

annotationTypes:
  supportsOnlyOneTargetLocationType:
    allowedTargets: TypeDeclaration

当允许多个目标类型时,使用数组:

annotationTypes:
  supportsMultipleTargetLocationTypes:
    allowedTargets: [ Library, Overlay, Extension ]

⚠️ 如果没有定义 allowedTargets,则该注解类型默认可以用于所有支持的位置。

3. 应用注解类型

在 RAML API 规范的根级别定义好注解类型之后,就可以将它们应用到具体的目标位置,并提供相应的属性值。在目标位置中使用注解类型的行为,就称为对该目标的 注解

3.1. 语法

应用注解类型的语法如下:

  • 将注解名称用括号 () 包裹,作为目标位置的一个属性。
  • 提供注解类型所需的属性值。
  • 如果注解类型定义在某个 RAML 库中,使用 库名.注解名 的格式引用。

3.2. 示例

下面的示例展示了如何将前面定义的注解类型应用到 API 中的资源和方法上:

/foos:
  type: myResourceTypes.collection
  (simpleImplicitStringValueType): alpha
  ...
  get:
    (simpleExplicitStringValueType): beta
  ...
  /{fooId}:
    type: myResourceTypes.item
    (complexValueType):
      prop1: 4
      prop2: testing
      prop3: true

4. 实际应用场景

注解的一个典型用途是 为 API 定义和配置测试用例

假设我们要开发一个 RAML 处理工具,可以根据注解自动生成 API 测试用例。可以定义如下的注解类型:

annotationTypes:
  testCase:
    allowedTargets: [ Method ]
    allowMultiple: true
    usage: |
      使用此注解来声明一个测试用例。
      每个方法上可以多次使用该注解。
    properties:
      scenario: string
      setupScript?: string[]
      testScript: string[]
      expectedOutput?: string
      cleanupScript?: string[]

然后在 /foos 资源的方法上配置多个测试用例:

/foos:
  type: myResourceTypes.collection
  get:
    (testCase):
      scenario: No Foos
      setupScript: deleteAllFoosIfAny
      testScript: getAllFoos
      expectedOutput: ""
    (testCase):
      scenario: One Foo
      setupScript: [ deleteAllFoosIfAny, addInputFoos ]
      testScript: getAllFoos
      expectedOutput: '[ { "id": 999, "name": Joe } ]'
      cleanupScript: deleteInputFoos
    (testCase):
      scenario: Multiple Foos
      setupScript: [ deleteAllFoosIfAny, addInputFoos ]
      testScript: getAllFoos
      expectedOutput: '[ { "id": 998, "name": "Bob" }, { "id": 999, "name": "Joe" } ]'
      cleanupScript: deleteInputFoos

✅ 通过这种方式,我们可以将测试逻辑与 API 定义紧密集成,便于自动化工具生成测试脚本。

5. 总结

本教程展示了如何通过自定义 注解 来扩展 RAML API 规范的元数据。

我们首先介绍了如何使用 annotationTypes 声明注解类型,并列举了注解可以应用的目标位置。

接着演示了如何在 API 中使用注解,以及如何限制注解的使用范围。

最后,我们通过一个测试用例的示例,展示了注解在实际开发中的潜在用途。

📚 想了解更多关于 RAML 注解的内容,可以查阅 RAML 1.0 规范文档

完整示例代码可在 GitHub 项目中查看:annotations 示例项目


原始标题:Define Custom RAML Properties Using Annotations

« 上一篇: Java Web周报112
» 下一篇: 所有Spring Data指南