Vue+fastifyで外部APIを叩いてみた


はじめに

Vue.jsでフロントを作るとき、よく サーバー経由で外部API叩きたい ってことがあり、今回その実装方法を試してみたのでそのメモです。
Vueとよく一緒に使われるフレームワークとしてexpressがありますが、今回はexpressではなくfastifyを使ってみました!

そして外部APIとしてkintoneに対してAPIを叩いています。

fastify とは

後発のNode.jsフレームワークでまだドキュメントやリファレンスは少ないけど、async/await にデフォルトで対応していたり、expressよりパフォーマンスが高かったり結構良さげらしい。
フレームワークの比較については、以下のサイトが参考になります。express / koa / fastify について細かく記載されていてわかりやすかったです。

▼ Node.jsフレームワークを比較して見えたそれぞれの特徴
https://www.wantedly.com/companies/company_3239475/post_articles/179467

作ったもの

こんな動きをするものです。kintoneのデータがVue上(Web上)で確認できればOKです。あとは好きなようにテーブル表示したりリスト表示したり。

構成はこんな感じです。
そもそもクロスドメイン制約によりWebから直接APIが叩けないので、サーバー側を用意しないといけないです。

手順

ざっくり流れを箇条書きで書くとこうなります。

  • vue-cliのインストール
  • 作業ディレクトリの作成
  • Vue側の設定
    • axiosのインストール
    • HelloWorld.vueの修正
    • 実行
  • fastify側の設定
    • ツールのインストール
    • index.jsの作成
    • 実行
  • 動作チェック

全体準備

ではさっそく。まずはvue-cliのインストールからやります。

$ npm i -g @vue/cli

※ すでにグローバルで入っていればインストールは必要ありません。

作業ディレクトリを作って移動します。

$ mkdir my_project; cd my_project

ちなみに、これから作成するディレクトリ構成はこんな感じになります。

my_project/
  ├ front/ #フロントエンド用
  └ back/ #バックエンド用

※ node_modules関連は書いてませんがそれぞれ存在します。

Vue側(フロントエンド側)の設定

$ vue create front

vueの雛形が生成されます。今回はVueからfastifyに対してのリクエストにaxiosを使うのでそれもインストールします。

$ cd front
$ npm i --save axios

src > components > HelloWorld.vue を修正します。

HelloWorld.vue
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <button @click="post">データ取得</button>
    <p>{{ kin }}</p>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'HelloWorld',
  data() {
    return {
      kin: ''
    }
  },
  props: {
    msg: String,
  },
  methods: {
    async post() {
      const kintoneData = await axios.post('http://localhost:3000/getData', {app: 836, id: 20});
      this.kin = kintoneData;
      console.log(kintoneData);
    }
  }
}
</script>
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

せっかくなのでVueからfastifyへオブジェクトを渡してそれをパラメータにAPIを叩くようにしてみました。
テンプレそのまま利用しているのであれですが、変更している点としては、

  • HTMLのいらない部分を削除
  • HTMLにボタン配置
  • axiosのインポート
  • ボタンとメソッドの紐付け

とかです。
※ 本当はapi.jsとか別途作ってコンポーネント化するべきだと思いますが、今回はシンプルに。

フロントエンドの実行

修正ができたら、 npm run serve で実行します。多分 http://localhost:8080 でアクセスできると思います。

fastify側(バックエンド側)の設定

必要なツールのインストールをします。

$ mkdir back; cd back
$ npm init
$ npm i --save fastify fastify-cors nodemon

# kintoneのSDK
$ npm i @kintone/rest-api-client
  • fastify: Node.js フレームワーク
  • fastify-cors: fastifyをCORS対応させるためのもの
  • nodemon: ファイルを監視して変更があったらスクリプトを再実行してくれるやつ。便利。
  • @kintone/rest-api-client: kitnoneのAPIを叩きやすくするツール。kintone使わないなら必要ないです。

バックエンドで実行させるJSファイルを作ります。

$ touch index.js

中身はこんな感じ。3000ポートを使ってます。

index.js
const fastify = require('fastify')();
fastify.register(require('fastify-cors'));

fastify.post('/getData', async (request, reply) => {
  // ここに外部APIへのリクエストを書く

  // 引数のreplyを使ってWeb側へデータを渡す
  reply.send({message: 'Hello World!'});
});

fastify.listen(3000);

kintoneへデータ取得のAPIを叩く処理を書くとこんな感じ。

index.js
// kintoneの設定
const {KintoneRestAPIClient} = require('@kintone/rest-api-client');
const client = new KintoneRestAPIClient({
  baseUrl: 'https://{subdomain}.cybozu.com',
  auth: {
    apiToken: '{api_token}'
  }
});

const fastify = require('fastify')();
fastify.register(require('fastify-cors'));

fastify.post('/getData', async (request, reply) => {
  // requestでVue側からオブジェクトを受け取る
  const data = await client.record.getRecord({app: request.body.app, id: request.body.id});
  console.log(data);
  reply.send({message: JSON.stringify(data)});
});

fastify.listen(3000);

npm startでnodemonを使ってindex.jsが動くように、package.jsonを修正します。

package.json
~~
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "./node_modules/nodemon/bin/nodemon.js index.js"
  },
~~

バックエンドの実行

npm start すれば、3000ポートで待機されます。
nodemonを使うことで、index.jsを修正すると自動で npm start が再度走るのでとても楽です。

fastify側(バックエンド側)だけでの動作チェック

fastifyのメソッドを get に変更すれば、ブラウザ上で簡単に動作チェックもできます。

index.js
const fastify = require('fastify')();
fastify.register(require('fastify-cors'));

fastify.get('/test', async (request, reply) => {
  // ここに外部APIへのリクエストを書く

  // 引数のreplyを使ってWeb側へデータを渡す
  reply.send({message: 'Hello World!'});
});

fastify.listen(3000);

npm start して、 http://localhost:3000/test にアクセスして、 reply.send()の内容が表示されていればOKです。
/test部分はコード内で指定しているものに適宜変更してください。

さいごに

雰囲気はexpressと変わらないですね。やはりasync/awaitがデフォルトで使えるのが強い。
パフォーマンスについてはそこまですごいもの作らないから正直わからないです(´-ω-`)

今回はlocalhostで作成していたので、ngrokとか使ってhttps通信できるようにもしてみたい。Webhookとか受け取ってみたい。
実装できたらまた記事化します。

それでは!≧(+・` ཀ・´)≦

余談

express の解説記事を探している中で、不覚にも以下のサイト内の画像につい笑ってしまった
https://techacademy.jp/magazine/16119

田島さん、めっちゃスルーするやん!!