Windowsで、サクサクvue.jsからAPIコールを試してみる

FNCT創造工学演習、予備実験向けにハンズオンを作成しました。

過去記事の[Windowsで、GUIを使ったサクサクvue.js開発してみる](https://qiita.com/hIDDEN_xv/items/cb704a03d2b806f9e8eb)と
[WindowsでFirebase CloudFunctionsとRealtimeDatabaseを使ってみる](https://qiita.com/hIDDEN_xv/items/222820f8b7d4c357410e)のハンズオンを終えている前提で、vue.jsからWeb APIをコールするハンズオンを体験してみよう。

## axiosをインストールする
Web APIにHTTPでアクセスするため、シェアの多いaxiosというライブラリを利用する。
GUI環境を使って簡単にインストールできるので試してみよう。

vue GUI左端のメニューから依存アイコンを選択し、右上の「＋ 依存をインストール」ボタンをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69744/18218d1e-7f95-7fa4-4702-ff9543287fd8.png)

「プラグインを検索する」テキストボックスに「axios」とタイプすると、すぐ候補がリストアップされる。
ここでは一番上に表示されている「axios」を選択して、「インストール」ボタンをクリックしよう。しばらく待てばインストール完了だ。簡単すぎる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69744/42816a0d-4037-a433-9219-94f6dfaf908c.png)

## ボタンを押したらAPIアクセス
### 呼ばれる側のAPI（Functions）の準備
JavaScriptでAPIコールをしようとすると、そのままではうまくいかない。通常APIサーバーはセキュリティ確保のため異なるドメインからのアクセスを受け付けないが、CORSという仕組みにより異なるドメイン（Cross Origin）からアクセスできるようになる。
そのための準備をしていきたい。

[前回の記事](https://qiita.com/hIDDEN_xv/items/222820f8b7d4c357410e)で作成していたフォルダ以下に「functions」というフォルダがあるので、そこで下記コマンドを実行する。

```コマンドプロンプト:/functions
> npm install cors
```

加えて、index.jsファイルに下記の行を追加する。

```javascript:/functions/index.js
const functions = require('firebase-functions');
const cors = require('cors')({origin: true}); // ← この行を追加

const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.helloWorld = functions.https.onRequest((request, response) => {
  cors(request, response, () => { // ← この行を追加
    const name = request.query.name;
    response.send(`Hello, ${name}!`);
  }); // ← この行を追加
});
```

最後にここまでを、Firebaseにデプロイする。

```コマンドプロンプト
> firebase deploy
```

### APIアクセスを追加する
vue.js側のコードに戻って、下記のようにHelloWorld.vueを編集する。
`<template>` に1箇所、 `<script>` に2箇所を、コメントを参考に追記してほしい。
なお `https://us-central1-sample-00000.` のURLの部分は、自分のデプロイURLに差し替えるのを忘れずに。

```vue:/src/components/HelloWorld.vue
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <button v-on:click="kick">kick me!</button>
    <p>
      <input type="text" v-model="name" /><br />
      {{ name }}
    </p>
    <!-- ここから -->
    <p>
      <button v-on:click="api">APIコール</button><br />
      {{ apiResult }}
    </p>
    <!-- ここまでを追加 -->
  </div>
</template>

<script>
import axios from "axios"; // ← この行を追加

export default {
  name: 'HelloWorld',
  data() {
    return {
      name: "", // ← 末尾にカンマ(,)を追加
      apiResult: "" // ← この行を追加
    }
  },
  props: {
    msg: String
  },
  methods: {
    kick: function (event) {
      this.msg += " kick!";
    }, // ← 末尾にカンマ(,)を追加
    // ここから
    api: function (event) {
      axios
        .get( "https://us-central1-sample-00000.cloudfunctions.net/helloWorld" )
        .then( response => ( this.apiResult = response.data ) )
    }
    // ここまでを追加
  }
}
</script>
```

完成したら、vueのページをリロードして「APIコール」ボタンをクリックしてみよう。
下記のように、ボタンのすぐ下にAPIコール結果が表示されれば成功だ。

```
Hello undefined!
```
### パラメータを渡す
さて、undefinedとはなんだろう。
helloworldは渡されたパラメータにHelloを返すようにしていたので、パラメータをちゃんと渡してあげよう。

HelloWorld.vueを下記のように修正する。

```vue:/src/components/HelloWorld.vue
    api: function (event) {
      const url = "https://us-central1-sample-00000.cloudfunctions.net/helloWorld?name=" + this.name; 
      axios
        .get( url )
        .then( response => ( this.apiResult = response.data ) )
    }
```

テキストボックスに入力されたテキストを、APIにパラメータで渡すようになった。
実行結果は下記のようになるはずだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69744/d6a2e60b-6f36-5ee2-43f9-fc54a5dbb14e.png)

以上で、vue.jsのフロントエンドからFirebase Functionsのバックエンドの機能を呼び出し、結果を表示できるようになった。
これを組み合わせていけば、複雑でかつサーバと協調して動作するアプリケーションが開発できるようになる。