vue.js と axios を使って Web API にアクセスする

こんにちは。エクセルソフトの田淵です。

この前は MySQL を使った DB のコンテナーを作りました

CData API Server を使えばすぐに MySQL から API が作れるので、今度はその API にアクセスするフロントエンドを作ってみましょう。

ただ、私は Web フロントエンドには全く詳しくないので、Vuejs-jp が日本マイクロソフトが開催した de:code 2019 のイベントで公開してくれた Vue.js 初心者向けハンズオン – Visual Studio Code, TypeScript, Element 編 をベースにやっていきたいと思います。

またきちんと理解できていないので、メモ書きになってしまっている点はご容赦ください。

vue cli を使う

Lab 0 – 開発環境の準備 そのままなのですが、

npm install -g @vue/cli

で vue cli をインストールします。ハンズオンドキュメントでは 3.x でしたが、2019/10/30 現在では

> vue --version
@vue/cli 4.0.4

でした。

Lab 0 から順番にやっていけば一通りの流れを体験できます。Lab 4 までやって、なんとなく、Vue と Vue Router が分かった気になったところで、次の応用編でなんと API にアクセスするハンズオンまで用意されていました。完璧かよ…

Axios を使う

Vue で Web API にアクセスするには Axios というライブラリを使うのが一般的なようです。

最終的には以下のような Web のフロントエンドができました!

ソースは GitHub に上げておきました。

API へのアクセス

詳細は

を見ていただくのが良いかなと思いますが、気になった点やハマった点などを記載しておきます。

Vuejs のハンズオン資料では、

async invokeTranslator(text: string): Promise {
  const res: AxiosResponse = await axios.post(
    "https://" + this.apiPrefix + "-vue.azurewebsites.net/api/translate",
    {
      target: text
    }
  );
  return res.data;
}

Promise<T> を受け取るメソッド(多分)なんですが、公式の資料には

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

とシンタックスチェーンで書いてあるんですよね。ハンズオンの書き方とどう違うのかまだ理解できていないので、悩んでいます。特に Any って型?の扱いが難しいですね…

戻り値の取得

今回作成している API では、axios.get() で受け取る JSON は以下のような状態です。

{
    "@odata.context": "http://XXXXXX:8080/apiserver/api.rsc/$metadata#city",
    "value": [
        {
            "Address": "Mita (次のビルを除く)",
            "Prefecture": "Tokyo To",
            "Zip": "1080073",
            "JP_Address": "三田 (次のビルを除く)",
            "JP_Prefecture": "東京都",
            "City": "Minato Ku",
            "JP_City": "港区",
            "ID": 38389
        },
        {
            ...略...
        },
        ...略...
        {
            ...略...
        }
    ]
}

このような JSON が AxiosResponse には

res.data.value に配列が入っている状態です。なので、以下のような Address クラスを用意して Promise の戻り値として Promise<Address[]> を受け取ってあげるだけでした。

class Address {
  Id: number = 0;
  Zip: string = "";
  Prefecture: string = "";
  City: string = "";
  Address: string = "";
  JP_Prefecture: string = "";
  JP_City: string = "";
  JP_Address: string = "";
}

C# だと JsonConvert.DeserializeObject<T>(json) しないといけないので、そのまま渡せることにビックリしました!笑

VS Code でのデバッグ

VS Code によるデバッグ — Vue.js

本家にもドキュメントがありますので詳しくはこちらをご覧ください。

今までの手順では、ソースのルートディレクトリに vue.config.js が存在しないので、作成して次の項目を追加します。

module.exports = {
  configureWebpack: {
    devtool: 'source-map'
  }
}

デバッグ実行する時に利用する .vscode/launch.json はドキュメントを参考にして、webRoot の場所を適切な場所に変更してください。またポート番号も実際に使っているものに変更しましょう。

VS Code の TERMINAL 欄で npm run serve でデバッグサーバーを立てて、そこからデバッグペインで launch.json で指定した設定でデバッグします。

ちゃんとデバッグできていますね!

複数人で作業する

私は Windows と Mac を常時使っているので、両方で開発することが多いです。今回は途中まで Windows で作業して途中で Mac に切り替えました。Mac に clone して実行しようとしたらライブラリが無いって言われました。それぞれの環境で npm install すればいいんですね〜的なツイートをしたら、npm ci というのを教えてもらいました。

あなたがnpm installをしてはいけない時 - Qiita

package-lock.json を Git で同期して npm ci すると全てのマシンで同じ環境が再現できるようです!

https://platform.twitter.com/widgets.js

環境変数

dotenv というパッケージの機能を使うと環境変数などを隠蔽して利用できます。

詳しくは公式ドキュメント Modes and Environment Variables | Vue CLI を参照してください。

vue 3.x 系で環境変数を使うには、プロジェクトのルート.env.env.local などのファイルを用意します。そのファイルに、ドキュメントの通りに例えば VUE_APP_TOKEN などと VUE_APP の prefix とともに環境変数名を指定して利用します。console.log(process.env.VUE_APP_SECRET) などで使用できます。

.env.local をちゃんとプロジェクトのルートに置いていなかったという凡ミスとして、デバッグ中に undefined のエラーがずっと出ていて値が取れず、辛かったです…w

まとめ

Vue.js と Axios を使うと API にアクセスする Web サービスが凄く簡単に作れることがわかりました!

MySQL から API を作るには CData API Server が楽ちんです!

以上です。

タイトルとURLをコピーしました