RAML语法简单介绍

人类可读的raml语法

开始设计时,首先创建一个包含以下内容的RAML文件:

#%RAML 0.8
title: This is My API
baseUri: http://api.domain.com
version: 1

在以上代码中,我们首先声明这是一个RAML规范,它对应RAML 0.8,并声明API的标题、基本URI、以及这个API的版本号。
在RAML中声明资源非常简单,只需使用/resourceName格式。而添加方法也同样便捷,只需引用相应的HTTP谓词即可:

#%RAML 0.8
title: This is My API
baseUri: http://api.domain.com
version: 1

/resource1:
  get:
    description: This gets the collection of resource1
  post:
    description: This adds a new item to the collection

RAML让你能够定义多种相应,返回不同的状态码、头信息以及响应体。例如:

#%RAML 0.8
title: This is My API
baseUri: http://api.domain.com
version: 1

/resource1:
  get:
    responses:
      200:
        headers:
          cache-control:
            example: |
              public, no-cache, no-store

        body:
          application/json:
            example: |
              {"name":"Michael Stowe"}
          application/xml:
            example: |
              <name>Michael Stowe</name>
      400:
        #...
      401:
        #...

RAML本身还有大量的其它特性,让你通过schema与参数定义完整的API。它还允许你使用资源嵌套、文件引用(可以引用多个文件,以保持规范的易读性和易组织性),甚至是变量或属性的设置,从而在整个规范中保持一致性。

举例来说,你可以在规范中按以下方式利用这些特性:

#%RAML 0.8
title: This is My API
baseUri: http://api.domain.com
version: 1

/resource1:
  get:
    responses:
      200:
        body:
          application/json:
            schema: |
              {
                  "type": "object",
                  "$schema": "http://json-schema.org/draft-03/schema",
                  "id": "http://jsonschema.net",
                  "required": true,
                  "properties": {
                    "firstName": {
                      "type": "string",
                      "required": true
                    },
                    "lastName": {
                      "type": "string",
                      "required": true,
                      "minLength": 3,
                      "maxLength": 36
                    }
                  }
              }

  /sub-resource:
    get:
      queryParameters:
        firstName:
          description: "the user’s first name"
          example: John
          required: true
          type: string

对开发者十分友好

RAML的优点不仅在于简单的格式与丰富的工具,它还能够让开发者应用编码的最佳实践,例如模式与重用代码。这不仅能够极大地减少开发者的工作,还能够促使API在不同的资源与方法中保持统一性。虽然你总是能够抽象出一套schema,以保持规范的良好组织,或是通过“!include”命令引入schema、示例与其它RAML代码片段,但RAML还提供了两个额外的实用与独特的模板特性:即traits与resourceTypes

通过traits定义通用属性

RAML的traits特性允许你为方法(GET、PUT、POST、PATCH、DELETE等等)定义通用的属性(或traits),例如它们是否可过滤、可搜索或是可分页。

在创建trait时,你实际上是创建了一份模板,它能够通过接受参数为方法提供属性,只需几行代码就能够完成。同时为你所需的trait提供了最大程度的灵活性与自定义能力:

traits:
-searchable:
  queryParameters:
  query:
  description: |
    JSON array [{"field1","value1","operator1"},…] <<description>
  example: |
    <<example>>

/people:
  get:
    is: [searchable: {description: "search by name", example: "[\"firstName\"\,\"Michael\",\"like\"]"}]  

通过ResourceTypes为资源定义模板

此外,与traits相似,resourceTypes也允许你为资源本身创建模板,以此调用通用的方法与响应。打个比方,对于Collection这种资源类型来说,你可能会大量用到POST与GET方法,并且通常会返回200、201或400等状态码。只要将它定义为一种resourceType,你就能够通过两行代码就完成调用,而无需为你所创建的每种资源都加入相同的方法与状态码。

resourceTypes:
- collection:
    description: Collection of available <<resourcePathName>>
    get:
      description: Get a list of <<resourcePathName>>.
      responses:
        200:
          body:
            application/json:
              example: |
                <<responseVariable>>
        400:
          #...
        401:
          #...

/people:
  type:
    collection:
      responseVariable: |
        {
         "name" : "Michael Stowe",
         "company" : "MuleSoft",
        }

你甚至可以在resourceTypes中定义可选的方法,只需为该方法加上一个问号(?)即可。这种可选方法只有在定义了该方法的资源中才会被引入,这就为你赋予了更大的灵活性。

注:这里只介绍了一些基本用法,详细用法请参考官方语法介绍