OpenAPIに触れてみた話

はじめに

こんにちは!

ご無沙汰しております、ecbeing 湯上です。

気が付いたら新卒4年目ももう折り返しの季節・・・

時の流れの早さをひしひしと実感している今日この頃です。

さて、今回は業務の一環でOpenAPIに触れる機会がありましたので、簡単に特徴や利用方法などをご紹介しようと思います。

目次

OpenAPIとは

OpenAPI とはREST APIを記述するための標準的なフォーマットのことで、yaml/jsonファイルを利用してREST APIの仕様を定義するものです。 正式にはOpenAPI Specification(OAS)と呼ばれます。


↓公式ドキュメント swagger.io


Swagger(Swagger Specification)というワードを聞いたことがある方もいらっしゃるかと思います。

ざっくり言うと、OpenAPI(v3)の前身が Swagger(v2)であり、 現在では、SwaggerOpenAPIを利用したツール群のことを指すようです。

OpenAPIのメリット

「OpenAPIは便利だ」とよく言われますが、一般的に語られるメリットとしては以下があります。

  • 標準化されたフォーマットのため、設計者によって記述がばらつかない
  • 定義がテキストベースのため、バージョン管理システムと組み合わせて変更を管理しやすい
  • ツールを利用した様々な自動化ができる
    • コーディングの自動化(Open API Generator
    • 簡単にモックサーバーを立ち上げることができる(Stoplight Prism
    • ドキュメント生成(Open API Generator) など…

企業での開発や個人開発に問わず、多くのメリットがありますね。

実際に試してみよう

今回は、以下の4つを試してみたいと思います。

  • Swagger Editorを利用して、yamlファイルを作成する
  • OpenAPI Generatorを利用してC#ソースを作成する
  • Stoplight Prismを利用してモックサーバーを立ち上げる
  • モックサーバーを利用して生成したソースコードの動作を確認する

1. yamlファイルを書いてみよう

https://editor.swagger.ioを利用して、サンプルAPIを作成してみます。

Webページ上でエディタが開きます。

editor.swagger.io

今回はサンプルとしてとても単純なHelloWorldを返すAPIを定義してみましょう。

下記のyamlをエディタにコピー&ペーストしてみてください。

openapi: 3.0.3
info:
  title: OpenAPI 3.0 サンプル(ecbeing labs)
  description: ecbeing labs(イーシービーイング・ラボ) OpenAPIのサンプルソースです。
  version: 1.0.0
servers:
  - url: http://{host}:{port}
    variables:
      host:
        default: 127.0.0.1
      port:
        default: '4010'
tags:
  - name: hello-world
    description: こんにちは世界

paths:
  /hello:
    get:
      tags:
        - hello-world
      summary: HelloWorldを返します。
      description: HelloWorldを返します。
      operationId: get-hello-world
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  mesasge:
                    type: string
                    example: "Hello World!"         
        '404':
          description: World not found

すると左側のyamlに対応したOpenAPIのドキュメントが右側に表示されます。

Swagger Editorのスクリーンショット

Get /hello の Vをクリックしてみると各エンドポイントの詳細を確認することができます。

※今回はHelloWorldしかないですが・・・🙁

/helloの詳細

2. クライアントアプリケーションのソースを生成してみよう

つづいて、サンプルのyamlを利用してプログラムから利用するためのソースファイルを作成してみましょう。

今回はOpenAPIv3に対応しているOpenAPI Generatorを利用してソースファイルを生成してみます。

言語は弊社でよく利用されているC#を選択しました。


↓公式サイト openapi-generator.tech

※今回は作業環境の都合でmavenに存在するスタンドアロンのjarファイル(Java)を利用して生成しています

※公式サイトではより手軽なnvmが紹介されていますので、お好きなプラットフォームのツールをご利用ください


「yamlファイルを書いてみよう」の節で開いたhttps://editor.swagger.ioからyamlファイルをダウンロードします。

File > Save as YAMLを選択します。

yamlファイルをダウンロードする

jarファイルと同じディレクトリにDLしたopenapi.yamlを配置して、コマンドを実行します。

java -jar .\openapi-generator-cli-7.0.1.jar generate -i openapi.yaml -g 'csharp-netcore' -o '.\output\' --library httpclient

すると同じディレクトリにoutputというフォルダが生成され、内部にC#のソリューションファイルが生成されます!

outputフォルダ内

非常に簡単ですね。

あとは煮るなり焼くなり自由にできます!

3. モックサーバーを立ち上げてみよう

クライアント側のソースは生成できました。

次は生成されたソースを試すために、Stoplight Prismを利用してモックサーバーを立ち上げてみましょう。


↓公式サイト stoplight.io


今回はコンソールアプリケーションのprism-cliを利用してローカルで検証してみます。

github.com


DLしたexeファイルと同じディレクトリにopenapi.yamlを配置して、コマンドを実行します。

.\prism-cli-win.exe mock openapi.yaml

するとログが出力され、モックサーバーが立ち上がります!

実行した際のコンソールログ

試しにコンソールに出力されたパスにアクセスしてみると、「Hello World!」と表示されていますね!

yaml中のexample:に定義した文字列が返却されています。

テストでアクセスしたときのブラウザ表示

4. 生成したソースを動かしてみよう

さて、最後にモックサーバーを利用して、生成したC#ソースの動作確認をしてみましょう。

「クライアントアプリケーションのソースを生成してみよう」の節で作成したoutputフォルダに出力されたOrg.OpenAPITools.slnをVisual Studioで開いてみます。


そして、APIを呼び出すためのコンソールアプリケーションをソリューションに追加します。

Visual Studio

※今回はOpenApiTestAppという名前でコンソールアプリを追加しました。

コンソールアプリにOrg.OpenApiToolsプロジェクトの参照を追加し、テストソースを書いて実行してみましょう。

生成したソースを実行してみる

すると、正しく Hello World!という文字列が取得できていることが確認できました!

このように非常に簡単な操作で、APIリクエストを実行できていることが分かります。

【余談】 OpenAPI Generator利用中につまづいたこと

ここからは余談になりますが、OpenAPI Generatorでのソース生成中につまづいた点があったので、この場に残しておきたいと思います。

OpenAPIでは、oneOfというキーワードを利用することで、 一つのエンドポイントに対して複数のリクエスト内容・レスポンス内容を定義することができます。

swagger.io

先ほど作成したyamlファイルを修正して実装してみましょう。

# 生成に失敗する定義
responses:
  '200':
    description: 成功
    content:
      application/json:
        schema:
          oneOf:
          - title: 'メインレスポンス'
            type: object
            properties:
              mesasge:
                type: string
                example: "Hello World!"
          - title: 'サブレスポンス'
            type: object
            properties:
              simpleMesasge:
                type: string
                example: "Hello!" 

OpenAPI Generatorを利用することで簡単にドキュメントを生成できるのですが、 その都合上titleに日本語を利用して定義してしまい、正常にクラスファイルが生成できず、エラーとなってしまう事象が発生しました。

空の名前のクラスファイルが生成されてしまった

ツールで生成できないと困る・・・しかしドキュメントの仕様は守りたい・・・

結論、正常にソースを生成できるようにするため、Schema Objectとして構造化して定義する必要がありました。

※再利用性も高まるため利点しかないです

swagger.io

# 正常に生成できる定義
paths:
  /hello:
    get:
      tags:
        - hello-world
      summary: Get HelloWorld
      description: HelloWorldを返します。
      operationId: get-hello-world
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema:
                oneOf:
                - $ref: "#/components/schemas/helloMain"  #ここで参照する
                - $ref: "#/components/schemas/helloSub"
        '404':
          description: World not found
components:
  schemas:
    helloMain: #レスポンスのコンテンツを個別に定義
      type: object
      title: 'メインレスポンス'
      description: 'メインのレスポンスです'
      properties:
        mesasge:
          type: string
          example: "Hello World!"
    helloSub: 
      title: 'サブレスポンス'
      description: 'サブのレスポンスです'
      type: object
      properties:
        simpleMesasge:
          type: string
          example: "Hello!" 

schemaを作成することで正常に生成される

皆さんも日本語(マルチバイト文字?)を利用する際はご注意ください・・・

まとめ

以下今回のまとめです。

  • REST APIを定義する標準フォーマットであるOpenAPIを利用することでAPIのIF仕様を標準化できる
  • 公開されている各種ツールを利用することで様々な手間を省くことができる
    • API仕様の作成(Swagger Editor)
    • 実装・テストソース(OpenAPI Generator)
    • モックサーバー(Prism-Cli)
  • 【余談】OpenAPI GeneratorでoneOfや日本語を利用する場合は注意が必要
    • オブジェクトは適宜schemaで構造化する

おわりに

ここまでご覧いただきありがとうございます。

OpenAPIはただ標準化されたフォーマットとしてではなく、

その共通性や利便性からツールも多く作成され、エコシステムが広く広がっていることを実感しました。

またOpenAPI Generatorで生成されたソースは、オブジェクト指向プログラミングに触れたことがある人であれば、直感的に利用しやすくなっていると感じます。

※APIを生成(new)してOperation(GetHelloWorld)を呼び出す

ツールを組み合わせることで、テスト環境が公開されていないサービスでもモックサーバーを利用して、効率よくクライアントアプリケーションを開発することも可能ですね!

皆さんもぜひ OpenAPI Specification(OAS)を活用してみてはいかがでしょうか。

お知らせ

ecbeingでは新しい技術要素に触れていきたいエンジニアを募集しています!! careers.ecbeing.tech