APIクライアントとスタブAPIサーバーのプログラムを自動生成して、疎通確認をする

はじめに

今回はAPIクライアントとスタブAPIサーバー(以下、スタブサーバー)のプログラムを自動生成して、
疎通確認を行います。プログラムの自動生成にはOpenAPI Generatorを使います。
APIクライアントは、Create React Appで作成するプロジェクトに導入します。
スタブサーバーは、なるべく手間をかけずにローカルに立てる方針で進めていきたいと思います。

環境

  • Windows10
  • Node.js v14.16.0
  • npm v6.14.11
  • Yarn 1.22.10

プロジェクトを作成する

下記のコマンドを実行して、「react-openapi-sample」という名前のReact+TypeScriptのプロジェクトを作成します。

npx create-react-app react-openapi-sample --template=typescript

プロジェクトの作成後、プロジェクト直下に移動します。

cd react-openapi-sample

APIを定義したYAMLを作成する

今回はAPIを1つだけ定義した下記のYAMLを使います。
「openapi.yaml」と名前を付けてプロジェクト直下に保存します。
OpenAPI Generatorは、このYAMLからプログラムを自動生成します。

openapi: 3.0.3
info:
  title: サンプルAPI
  version: 1.0.0
servers:
  - url: http://localhost:8080
    description: stub API server
tags:
  - name: fruit
paths:
  /fruits:
    get:
      tags:
        - fruit
      description: フルーツの一覧を取得する
      operationId: getFruits
      responses:
        '200':
          $ref: '#/components/responses/GetFruitsResponse'
components:
  schemas:
    Fruit:
      type: object
      description: フルーツ
      properties:
        id:
          description: ID
          type: integer
          example: 1
        name:
          description: 名前
          type: string
          example: リンゴ
        producing_area:
          description: 生産地
          type: string
          example: 青森県
      required:
        - id
        - name
        - producing_area
    Fruits:
      type: object
      description: フルーツの一覧
      properties:
        fruits:
          type: array
          items:
            $ref: '#/components/schemas/Fruit'
      required:
        - fruits
  responses:
    GetFruitsResponse:
      description: /fruitsのレスポンス
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Fruits'

詳しいAPIの定義方法については、OpenAPI Specificationをご参照ください。

OpenAPI Generatorをインストールする

下記のコマンドを実行して、OpenAPI Generatorをインストールします。

yarn add @openapitools/openapi-generator-cli -D

APIクライアントのプログラムを自動生成する

下記のコマンドを実行して、APIクライアントのプログラムを自動生成します。
今回は自動生成するプログラムとして、TypeScriptかつ追加ライブラリが不要なFetch APIを指定しています。
併せてTypeScript v3.6以降と互換性のあるプログラムを生成するため、オプションに「-p typescriptThreePlus=true」を指定しています。

"node_modules/.bin/openapi-generator-cli" generate -i openapi.yaml -g typescript-fetch -p typescriptThreePlus=true -o src/openapi


-i:APIを定義したYAMLのパス
-g:自動生成するプログラム
-p:自動生成するプログラムのオプション設定
-o:プログラムの出力先

自動生成したAPIクライアントのプログラムを導入する

src/App.tsxを開き、以下の通り修正します。

import React, {useState} from 'react';
import {Fruit, FruitApi} from './openapi'; // OpenAPI Generatorで自動生成したプログラムをインポートする

function App() {
  const [fruits, setFruits] = useState([] as Fruit[]);
  const onClickHandler = async () => {
    // スタブサーバーにリクエストを送信し、レスポンスを受け取る
    const response = await new FruitApi().getFruits();

    // レスポンスをコンポーネントに反映する
    setFruits(response.fruits);
  };

  return (
    <div className="App">
      <div style={{width: 'fit-content', margin: '10px auto'}}>
        <button onClick={onClickHandler}>疎通確認</button>
      </div>
      <table style={{margin: '0 auto'}}>
        <caption style={{minWidth: '130px'}}>フルーツの一覧</caption>
        <thead>
        <tr>
          <th>ID</th>
          <th>名前</th>
          <th>生産地</th>
        </tr>
        </thead>
        <tbody>
        {fruits.map(fruit => {
          const {id, name, producingArea} = fruit;
          return (
            <tr key={id}>
              <td>{id}</td>
              <td>{name}</td>
              <td>{producingArea}</td>
            </tr>
          );
        })}
        </tbody>
      </table>
    </div>
  );
}

export default App;

フロントエンドのプログラムを実行する

下記のコマンドを実行して、Create React Appに組み込まれている開発用のサーバーを起動します。

yarn start

起動に成功すると以下の画面が表示されます。
開発用のサーバー起動成功時に表示される画面

スタブサーバーを構築する

ここからは、スタブサーバーをローカルに構築していきます。
先の手順で作成したプロジェクト直下で、新しくコマンドラインを開きます。

スタブサーバーのプログラムを自動生成する

下記のコマンドを実行して、スタブサーバーのプログラムを自動生成します。
今回は手間をかけずにサーバーを立てるため、Node.jsがインストール済みの環境で動かせる「nodejs-express-server」を選択します。

"node_modules/.bin/openapi-generator-cli" generate -i openapi.yaml -g nodejs-express-server -o stub-server


-i:APIを定義したYAMLのパス
-g:自動生成するプログラム
-o:プログラムの出力先

サーバープログラムに必要なライブラリをインストールする

プログラムの自動生成後、出力先として指定したフォルダに移動します。

cd stub-server

下記のコマンドを実行して、必要なライブラリをインストールします。

yarn install

レスポンスとして返すJSONデータを定義する

下記のJSONデータをレスポンスとして使います。
stub-dataフォルダを作成して、フォルダ内に「getFruitsResponse.json」と名前を付けて保存します。

{
  "fruits": [
    {
      "id": 1,
      "name": "リンゴ",
      "producing_area": "青森県"
    },
    {
      "id": 2,
      "name": "ブドウ",
      "producing_area": "山梨県"
    },
    {
      "id": 3,
      "name": "メロン",
      "producing_area": "茨城県"
    },
    {
      "id": 4,
      "name": "モモ",
      "producing_area": "山梨県"
    },
    {
      "id": 5,
      "name": "ナシ",
      "producing_area": "千葉県"
    }
  ]
}

JSONデータをレスポンスに設定する

stub-server/services/FruitService.jsを開き、下記コード内の★付きのコメント通りに修正します。

/* eslint-disable no-unused-vars */
// ★ここから下のpath, fs, configを追加する
const path = require('path');
const fs = require('fs');
const config = require('../config');

const Service = require('./Service');

/**
* フルーツの一覧を取得する
*
* returns Fruits
* */
const getFruits = () => new Promise(
  async (resolve, reject) => {
    try {
      // ★tryブロック内を下記の通りに修正する
      const responseJsonFilePath = path.join(config.ROOT_DIR, 'stub-data', 'getFruitsResponse.json');
      const response = JSON.parse(fs.readFileSync(responseJsonFilePath, 'utf8'));
      resolve(Service.successResponse(response));
    } catch (e) {
      reject(Service.rejectResponse(
        e.message || 'Invalid input',
        e.status || 405,
      ));
    }
  },
);

module.exports = {
  getFruits,
};

スタブサーバーを起動する

下記のコマンドを実行して、スタブサーバーを起動します。

yarn start

動作確認

フロントエンドのプログラムを実行した際に表示された画面の「疎通確認」ボタンを押下します。
ボタン押下後、スタブサーバーからレスポンスとして定義したJSONデータが返ってくることが確認できます。
動作確認

まとめ

今回はOpenAPI Generatorを使い、APIクライアントとスタブサーバーのプログラムを自動生成して、
疎通確認まで行いました。今回のサンプルはシンプルな構造のJSONデータでしたが、複雑な構造だと
手で作成するのは、さすがにしんどいです。まだまだ課題はありますが、少しずつ改良して実践的に
使っていけたらいいなと思います。


--------------------------
システム開発のご要望・ご相談はこちらから

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です