はじめに
今回は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データでしたが、複雑な構造だと
手で作成するのは、さすがにしんどいです。まだまだ課題はありますが、少しずつ改良して実践的に
使っていけたらいいなと思います。