RAML 0.8 API 仕様のよくある問題

次のセクションでは、RAML 0.8 で API 仕様を作成するときの作成者による一般的なエラーと、それらを解決するためのヒントについて説明します。

スキーマで予約済みの名前が使用されている

予約済み名前をスキーマ名として使用すると、エディターは次のメッセージを表示します。

‘schemaName’ cannot be used to name a custom schema

予約済みの名前としては、​string​、​integer​、​number​、​object​ などがあります。RAML 仕様で使用されている名前は、いずれもスキーマ名としては使用できません。

たとえば、次の API 仕様に対してエディターはメッセージを表示します。

#%RAML 0.8

title: Example API Spec

schemas:
 string:
   type: string

この問題を解決するには、スキーマ宣言で別の名前を使用します。

#%RAML 0.8

title: Example API Spec

schemas:
 customString:
   type: string

例の検証時の問題

ブール列挙の例で文字列データ型を使用していない

ブール列挙が文字列またはブール値のどちらであっても、例は文字列型でなければなりません。この違反の具体例として、次の API 仕様では例で間違ったデータ型を使用しています。

#%RAML 0.8
title: ExampleRAML
/nob:
  head:
    responses:
      204:
        headers:
          X-NOB-Exists:
            enum: [true, false]
            example: true

RAML 0.8 では、列挙値で文字列のみをサポートし、ブール値はサポートしません。また、上の RAML の例では、列挙のデータ型が宣言されていません。RAML 0.8 では、データ型が宣言されていない場合は ​string​ であると見なされます。

したがって、上の間違った例では、列挙の値を引用符で囲む必要があります。その理由は、例のデータ型を、例の対象となる要素と同じデータ型にする必要があるためです。

上の RAML 例の最後の 2 行は次のように記述しなければなりません。

...
            enum: ["true", "false"]
            example: "true"

必須プロパティを定義するスキーマの例で、そのプロパティを使用していない

必須プロパティを定義するスキーマの例では、そのプロパティを使用する必要があります。この問題の例で、次の API 仕様では、エンドポイント ​/order/{id}​ に対する応答を定義しています。この定義には ​get_order_response_schema.json​ と ​get_order_response.json​ という 2 つのファイルが含まれています。

#%RAML 0.8
title: ExampleRAML
version: 1.0
...
/order:
  displayName: Orders API
  /create:
    ...

  /{id}:
    displayName: Get Order by OrderId
    description: This operation will get an order by order ID from Salesforce.
    get:
      description: This operation returns the order from Salesforce by Fulfillment Order ID, not by the Salesforce unique ID.
      responses:
        200:
          body:
            application/json:
              schema: !include get_order_response_schema.json
              example: !include get_order_response.json

get_order_response_schema.json​ ファイルでは ​sfOrderId​ プロパティを必須プロパティとして定義しています。

{
	"type":"object",
	"$schema": "http://json-schema.org/draft-03/schema",
	"id": "http://com.mulesoft.demo.orders.get.json.order",
	"required":false,
	"properties":{
      ...
      "sfOrderId": {
        "type":"string",
        "id": "http://com.mulesoft.demo.orders.create.json.get.sfOrderId",
        "required":true
      },
  ...

スキーマの例は ​get_order_response.json​ に記述されています。しかしながら、必須プロパティの名前が ​sOrderId​ と間違っています。

{
  "orderId": 14523,
  "sOrderId": "fadfead3524523",
  "sfAccountId": "fedfes3653635",
  "orderName": "Order From Manufacturing-Company, Inc.",
  "total": 174.92,
  "orderType": "E-Commerce Order",
  "description": "8 widgets",
  "orderDate": "04-03-2018"
}

スキーマの例でスキーマが定義するデータ型を使用していない

たとえば、次の API 仕様のスキーマでは ​title​ プロパティのデータ型をオブジェクトとして定義していますが、スキーマの例では配列が使用されています。

#%RAML 0.8
title: ExampleRAML
schemas:
  - presentation: |
      {  "$schema": "http://json-schema.org/draft-03/schema",
         "type": "object",
         "properties": {
           "title":  { "type": "string" }
         }
      }

/presentations: &presentations
  type: { typedCollection: { schema: presentation } }
  get:
    responses:
      200:
       body:
         application/json:
           example: |
             [
              {
                  "title": "Presentation Video"
              },
              {
                  "title": "Environment Spec Report"
              }
              ]

ブールの例で値に 0 や 1 を使用している

ブールの例で使用できる値は「true」または「false」です。次の API 仕様では、フォームパラメーター ​is_public​ の例で使用されている値が間違っています。

#%RAML 0.8
title: ExampleRAML

/upload:
  post:
    description: |
      Upload a photo
    body:
      multipart/form-data:
        formParameters:
          title:
            description: The title of the photo.
          is_public:
            type: boolean
            example: 1

例にプロパティが含まれていない

例に対象となる型のプロパティが含まれていないと、エディターは違反メッセージを表示します。

should have required property 'property name'

次の API 仕様では、​age​ プロパティが例に含まれていません。

#%RAML 0.8
title: Example API Spec

/clients:
  get:
    responses:
      200:
        body:
          application/json:
            schema: |
              {
                "$schema": "http://json-schema.org/draft-03/schema",
                "properties": {
                    "firstName": {
                      "type": "string"
                    },
                    "lastName": {
                      "type": "string"
                    },
                    "age": {
                      "type": "number",
                      "required": true
                    }
                },
                "required": false,
                "type": "object"
              }
            example:
              firstName: John
              lastName: Smith

例にプロパティを追加するか、または型宣言でプロパティを省略可能として宣言してください。

次のケースでは、プロパティが例に追加されています。

#%RAML 0.8
title: Example API Spec

/clients:
  get:
    responses:
      200:
        body:
          application/json:
            schema: |
              {
                "$schema": "http://json-schema.org/draft-03/schema",
                "properties": {
                    "firstName": {
                      "type": "string"
                    },
                    "lastName": {
                      "type": "string"
                    },
                    "age": {
                      "type": "number",
                      "required": true
                    }
                },
                "required": false,
                "type": "object"
              }
            example:
              firstName: John
              lastName: Smith
              age: 30

次のケースでは、プロパティが省略可能として宣言されています。

#%RAML 0.8
title: Example API Spec

/clients:
  get:
    responses:
      200:
        body:
          application/json:
            schema: |
              {
                "$schema": "http://json-schema.org/draft-03/schema",
                "properties": {
                    "firstName": {
                      "type": "string"
                    },
                    "lastName": {
                      "type": "string"
                    },
                    "age": {
                      "type": "number",
                      "required": false
                    }
                },
                "required": false,
                "type": "object"
              }
            example:
              firstName: John
              lastName: Smith

title​ ノードの値がない

title​ ノードでは、次のように値を省略することはできません。

#%RAML 0.8
title:

要素の例で RAML 要素のデータ型を使用していない

すべてのケースにおいて、例のデータ型は、例の対象となる要素と同じでなければなりません。

次の間違った API 仕様では、クエリパラメーターを文字列として定義していますが、例では整数が使用されています。

#%RAML 0.8
title: ExampleRAML
/books:
  get:
    queryParameters:
      publicationYear:
        type: string
        example: 2016

JSON スキーマ内部の参照パスが無効である

JSON スキーマで ​$ref​ キーワードを使用する場合、指定するパスはスキーマのルートから始まっていなければなりません。たとえば、次のスキーマで ​input2​ プロパティに対して使用されている ​$ref​ キーワードでは、​input​ プロパティを参照するためのパスが間違っています。

#%RAML 0.8
title: ExampleRAML
version: v1
schemas:
- authCodeResponse : |
    {
      "$schema": "http://json-schema.org/draft-04/schema",
      "properties": {
        "input": {
          "type": "string"
        },
        "input2": {
          "$ref": "input"
        }
      },
       "type": "object"
    }

パスはスキーマのルートレベルから始まり、ツリー構造を下がって行かなければなりません。次のスキーマの例では、同じ ​$ref​ キーワードで正しいパスが使用されています。

{
      "$schema": "http://json-schema.org/draft-04/schema",
      "properties": {
        "input": {
          "type": "string"
        },
        "input2": {
          "$ref": "#/properties/input"
        }
      },
       "type": "object"
    }

使用されない URI パラメーターを宣言している

API 仕様で宣言した URI パラメーターが仕様内で使用されていない場合、エディターは次の警告メッセージを表示します。

unused uri parameter “parameter”

ベース URI パラメーターとして宣言されているパラメーターが使用されていない場合は、エディターは次の警告メッセージを表示します。

unused base uri parameter “parameter”

たとえば、次の API 仕様により 2 つの警告メッセージが表示されます。

unused uri parameter "unusedParam"
unused base uri parameter "unusedUriParam"
#%RAML 0.8
title: test

baseUri: http://param.raml/a/{baseUriParam1}/{nonExists}/{baseUriParam2}

baseUriParameters:
 baseUriParam1:
    type: string
 baseUriParam2:
    type: string
 unusedParam:
    type: string

/endpoint/{uriParam1}/{nonExistsUri}:
 uriParameters:
   uriParam1:
     type: string
   unusedUriParam:
     type: string

警告メッセージは、単純にこれらのパラメーターを宣言している行を削除するだけで表示されなくなります。

#%RAML 0.8
title: test

baseUri: http://param.raml/a/{baseUriParam1}/{nonExists}/{baseUriParam2}

baseUriParameters:
 baseUriParam1:
   type: string
 baseUriParam2:
     type: string

/endpoint/{uriParam1}/{nonExistsUri}:
 uriParameters:
   uriParam1:
     type: string

ペイロードのメディア種別を宣言していない

ペイロードの宣言でメディア種別が宣言されていないと、エディターは次のメッセージを表示します。

Payload media type is mandatory

たとえば、次の API 仕様に対してエディターはこのメッセージを表示します。

#%RAML 0.8
title: Example API Spec
/media:
 get:
   responses:
     200:
       body:
         type: string

この問題の解決法は 2 つあります。

  • ペイロード宣言でメディア種別をローカルに宣言する。

    #%RAML 0.8
    title: Example API Spec
    /media:
     get:
       responses:
         200:
           body:
            application/json:
             type: string
  • API 仕様でデフォルトのメディア種別をグローバルに指定する。

    #%RAML 0.8
    title: Example API Spec
    
    mediaType: application/json
    
    /media:
     get:
       responses:
         200:
           body:
             type: string

次の例では、グローバル宣言とローカル宣言の両方を使用しています。このケースでは、​mediaType​ ノードは ​application/json​ と ​application/xml​ を受け入れ可能なメディア種別として定義しています。最初の種別である ​Person​ は、どちらのメディア種別であっても構わずに本文を返します。2 番目の種別である ​Another​ は、ローカル宣言でグローバル宣言を上書きし、JSON の本文のみを返します。

#%RAML 0.8
title: New API
mediaType: [ application/json, application/xml ]
schemas:
  Person:
  Another:
/list:
  get:
    responses:
      200:
        body: Person
/send:
  post:
    body:
      application/json:
        schema: Another

!include​ タグを使用してフラグメントを参照していない

API 仕様で ​uses​ キーを使用してフラグメントを参照していると、エディターは次のメッセージを表示します。

Fragments must be imported by using '!include'

uses​ キーを使用してライブラリを適用していない

API 仕様で ​!include​ タグを使用してライブラリを適用していると、エディターは次のメッセージを表示します。

Libraries must be applied by using 'uses'

構文の問題

無効な JSON を含むスキーマが含まれている

schemas​ プロパティの値に含まれるファイルには、有効な JSON が必要です。

最初の例には ​appSwitcher.json​ というスキーマが含まれています。しかし、2 番目の例では、JSON にエラーがあり、最後の値の末尾が引用符であるべきところがカンマになっています。

#%RAML 0.8
title: ExampleRAML
schemas:
  - appSwitcher: !include schemas/appSwitcher.json
{
  "appMenuItems" : [
    {
      "type" : "Tabset" ,
      "content" : null ,
      "icons" : null ,
      "colors" : null ,
      "label" : "Call Center" ,
      "url" : "/home/home.jsp?tsid=02uxx00000056Sr"
    } , {
      "type" : "Tabset" ,
      "content" : null ,
      "icons" : null ,
      "colors" : null ,
      "label" : "Community" ,
      "url" : "/home/home.jsp?tsid=02uxx00000056Sw"
    } , {
      "type" : "Tabset" ,
      "content" : null ,
      "icons" : null ,
      "colors" : null ,
      "label" : "App Launcher" ,
      "url" : "/app/mgmt/applauncher/appLauncher.apexp?tsid=02uxx00000056Sx,
    }
  ]
}

JSON スキーマの例で無効な JSON を使用している

次の API 仕様では JSON スキーマの例が間違っていますが、有効な JSON を使用しなければなりません。

#%RAML 0.8
title: ExampleRAML
...
/api:
  get:
    responses:
      200:
        body:
          application/json:
            schema:
              {
                "type": "object",
                "required": true,
                "$schema": "http://json-schema.org/draft-03/schema",
                "properties": {
                  "a": {
                    "type": "boolean",
                    "required": true
                  }
                }
              }
            example:
              {
                "a: {
                  "a": ""
                }

ファセットが YAML マップを必要としている場合に YAML マップを提供していない

値としてマップが必要であるとして RAML 0.8 仕様でファセットが記述されており、API 仕様でマップが提供されていない場合、エディターにメッセージ「​YAML map expected​」が返されます。

次に、エラーの例を示します。

#%RAML 0.8
title: Test
version: 1.0
securitySchemes:
  basic:
    type: Basic Authentication
    settings:

エラーの修正方法は 2 つあります。

  • マップを値として提供する。

    #%RAML 0.8
    title: Test
    version: 1.0
    securitySchemes:
      basic:
        type: Basic Authentication
        settings:
          requestTokenUri: https://api.mysampleapi.com/1/oauth/request_token
  • マップを必要とするファセット (この場合は ​settings​) を削除する。

    #%RAML 0.8
    title: Test
    version: 1.0
    securitySchemes:
      basic:
        type: Basic Authentication

サポートされないプロパティを使用している

このエラーは未定義のファセットを使用した場合に発生します。

エラーメッセージの例

Property invalidfacet not supported in a RAML 0.8 webApi node​。​invalidfacet​ は、RAML 仕様で定義されていないファセットの名前です。

このエラーが生成される例を次に示します。

Table 1. 間違った例と正しい例
間違い 正しい
#%RAML 0.8
title: Test
invalidfacet:
version:
#%RAML 0.8
title: Test
version:

未定義の型をヘッダーで宣言している

このエラーは、存在しない型がヘッダーで指定されている場合に発生します。

エラーメッセージ

Cannot declare unresolved parameter

次の間違った例では、ヘッダー ​myHeader​ の値に入力ミスがあります。​string​ ではなく ​strang​ と指定されています。

Table 2. 間違った例と正しい例
間違い 正しい
#%RAML 0.8
title: test

/endpoint:
  post:
    headers:
      myHeader: strang
#%RAML 0.8
title: test

/endpoint:
  post:
    headers:
      myHeader: string