1. 概要

この記事では、 RESTful APIモデリング言語(RAML)を紹介します。これは、RESTfulAPIを記述するためのYAML1.2とJSONに基づいて構築されたベンダー中立のオープン仕様言語です。

単純なJSONベースのAPIを定義する方法を示すときに、基本的なRAML1.0の構文とファイル構造について説明します。 また、includeを使用して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}
  • / api / v1 / foos/{id}を削除します
  • GET / api / v1 / foos / name / {name}
  • GET / api / v1 / foos?name = {name}&ownerName = {ownerName}

そして、HTTP基本認証を使用してステートレスであり、HTTPSを介して暗号化されて配信されるようにAPIを定義しましょう。 最後に、データ転送形式としてJSONを選択しましょう(XMLもサポートされています)。

2.1. ルートレベルの設定

まず、 api.raml という名前の単純なテキストファイルを作成し( .raml プレフィックスを推奨します。名前は任意です)、1行目に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」という単語の前後に中括弧{}が使用されていることに注意してください。 これは、「 version」がプロパティを参照しており、展開されることをRAMLに伝える方法です。 したがって、実際の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のプレースホルダーを表し、上記のbaseUri宣言で見たようにルートレベルのRAMLファイルのプロパティを参照しません。 追加された行は、リソース / 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. 反応

URIパラメーター、HTTPメソッド、クエリパラメーターなど、APIのすべてのリソースを定義したので、次に、予想される応答とステータスコードを定義します。 応答形式は通常、データ型と例に関して定義されます。

以前のバージョンのRAMLとの下位互換性のために、データ型の代わりにJSONスキーマを使用できます。 セクション3でJSONスキーマを紹介します。

[注:以下のコードスニペットでは、3つのドット(…)のみを含む行は、簡潔にするために一部の行がスキップされていることを示しています。]

/ foos / {id}:での簡単なGET操作から始めましょう。

/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操作は、POST操作と同じ要求および応答本文を使用して200のHTTPステータスを返します。

リクエストが成功したときに返される期待される応答とステータスコードに加えて、エラーが発生したときに期待する応答の種類とステータスコードを定義できます。

指定されたIDのリソースが見つからない場合に、 / foos /{id}リソースでGETリクエストに対して期待される応答をどのように定義するかを見てみましょう。

        404:
          body:
            application/json:
              type: Error
              example: { "message" : "Not found", "code" : 1001 }

3. JSONスキーマを使用したRAML

データ型がRAML1.0で導入される前は、オブジェクト、リクエストボディ、およびレスポンスボディはJSONスキーマを使用して定義されていました。

データ型の使用は非常に強力ですが、それでもJSONスキーマを使用したい場合があります。 RAML 0.8では、ルートレベルのschemasセクションを使用してスキーマを定義しました。

これは引き続き有効ですが、スキーマの使用は将来のバージョンで廃止される可能性があるため、代わりにtypesセクションを使用することをお勧めします。 タイプスキーマ、およびタイプスキーマは同義語です。

JSONスキーマを使用して.ramlファイルのルートレベルで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セクションは次のようになります。

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の優れた点の1つは、ツールのサポートです。

RAML APIを解析、検証、およびオーサリングするためのツールがあります。 クライアントコード生成のためのツール。 HTMLおよびPDF形式のAPIドキュメントを生成するためのツール。 RAMLAPI仕様に対するテストを支援するツール。

SwaggerJSONAPIをRAMLに変換するツールもあります。

利用可能なツールのサンプルを次に示します。

  • API Designer –迅速で効率的なAPI設計を対象としたWebベースのツール
  • API Workbench – RAML0.8と1.0の両方をサポートするRESTfulAPIを設計、構築、テスト、および文書化するためのIDE
  • RAML Cop –RAMLファイルを検証するためのツール
  • RAML for JAX-RS –RAML仕様からJava+JAX-RSアプリケーションコードのスケルトンを生成するため、または既存のJAX-RSアプリケーションからRAML仕様を生成するためのツールのセット
  • RAMLSublimeプラグイン–Sublimeテキストエディター用の構文ハイライトプラグイン
  • RAML to HTML –RAMLからHTMLドキュメントを生成するためのツール
  • raml2pdf –RAMLからPDFドキュメントを生成するためのツール
  • RAML2Wiki – Wikiドキュメントを生成するためのツール(Confluence / JIRAマークアップを使用)
  • SoapUIRAMLプラグイン–人気のあるSoapUI機能APIテストスイート用のRAMLプラグイン
  • Vigia –RAML定義に基づいてテストケースを生成できる統合テストスイート

RAMLツールと関連プロジェクトの完全なリストについては、RAMLプロジェクトページにアクセスしてください。

7. RAMLの現状

RAML 1.0(RC)仕様は、2015年11月3日にリリース候補のステータスを取得し、この記事の執筆時点では、バージョン1.0は1か月以内に完成する予定でした。

その前身であるRAML0.8は、もともと2014年の秋にリリースされ、今でも無数のツールでサポートされています。

8. 参考文献

ここに、RAMLでの旅に役立つと思われるリンクをいくつか示します。

9. 結論

この記事では、RESTful APIモデリング言語(RAML)を紹介しました。 RAML 1.0(RC)仕様を使用して簡単なAPI仕様を作成するための基本的な構文をいくつか示しました。

また、構文上のショートカットを使用し、例、データ型、スキーマを「インクルード」ファイルに外部化することで、定義をより簡潔にする方法を見てきました。

次に、RAML仕様と連携して、日常のAPI設計、開発、テスト、およびドキュメント化タスクを支援する強力なツールのコレクションを紹介しました。

仕様のバージョン1.0の次の公式リリースと、ツール開発者の圧倒的なサポートにより、RAMLは今後も続くようです。