【JS】【TS】axios ~ 外部API通信ライブラリ ~

■ はじめに

TypeScript で、axios ってのを扱う可能性がでてきたので、メモ。

目次

【1】axios とは?
【2】Tips
 1)キャンセルするには
【3】サンプル
 例1:JavaScript での Hello world
 例2:TypeScript での Hello world(async/await)
 例3:TypeScript での POST送信(async/await)
 例4:Vue/TypeScript での Hello world(Promise.prototype.then())
 例5:Vue/TypeScript での リスト表示

【1】axios とは?

* 読み方は、「アクシオス」
* JavaScript/TypeScript などのクライアントサイドから
 外部API(e.g. REST) にアクセスできるライブラリ
* 正確にいうなら、axios の Github

https://github.com/axios/axios

より抜粋
~~~~~~~
Promise based HTTP client for the browser and node.js

[訳] ブラウザ&Node.jsのためのPromiseベースのHTTPクライアント
~~~~~~~

補足:Promise について

* 非同期処理で完了した際のレスポンスを表すオブジェクト
* 詳細は、以下の関連記事を参照のこと

非同期処理 ~ async/await, Promise ~
https://dk521123.hatenablog.com/entry/2021/01/16/202822

【2】Tips

1)キャンセルするには

* 以下の関連記事を参照のこと。

axios で リクエストに対してキャンセルするには
https://dk521123.hatenablog.com/entry/2021/03/24/110355

【3】サンプル

例1:JavaScript での Hello world

<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <title>Axios Demo</title>
  <!-- ★cdn でインストール★ -->
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="result">Result</div>

<script>
axios.get('https://jsonplaceholder.typicode.com/users')
.then(function (response) {
  // ★データ取得★
  console.log(response);
})
.catch(function (error) {
  // ★エラーハンドリング★
  console.log(error);
})
.finally(function () {
  // ★Finally★
  console.log('Done');
  var result = document.getElementById("result");
  result.innerHTML = 'See your console.log() <f12>';
});
</script>
</body>
</html>

例2:TypeScript での Hello world(async/await)

import axios from 'axios';

// async () ... は、以下のESLintエラー対応
// 「error TS1378: Top-level 'await' expressions are only allowed
// when the 'module' option is set to 'esnext' or
// 'system', and the 'target' option is set to 'es2017' or higher. 」
(async () => {
  const apiPromise = axios.get('https://jsonplaceholder.typicode.com/users');
  const response = await apiPromise;

  console.log('* 1) レスポンスデータ *******************');
  console.log(response.data);

  console.log('== レスポンスデータからIDリストを作成 ==');
  const idList = response.data.map((result: { id: string; }) => result.id);
  // e.g. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  console.log(idList);

  console.log('* 2) HTTPステータス *******************');
  // e.g. 200
  console.log(response.status);

  console.log('* 3) ステータスのテキスト *******************');
  // e.g. OK
  console.log(response.statusText);

  console.log('* 4) ヘッダー情報 *******************');
  console.log(response.headers);

  console.log('* 5) リクエスト時にaxiosへ渡した設定値 *******');
  console.log(response.config);

  console.log('* 6) レスポンスに対応しているリクエスト内容 ******');
  console.log(response.request);
})();

例3:TypeScript での POST送信(async/await)

* 以下のサイトに書いてあるサンプルを axios で実装。

https://jsonplaceholder.typicode.com/guide/

import axios from 'axios';

// async () ... は、以下のESLintエラー対応
// 「error TS1378: Top-level 'await' expressions are only allowed
// when the 'module' option is set to 'esnext' or
// 'system', and the 'target' option is set to 'es2017' or higher. 」
(async () => {
  const apiPromise = axios.post('https://jsonplaceholder.typicode.com/users',{
    headers: {
      'Content-type': 'application/json; charset=UTF-8',
    },
    body: JSON.stringify({
      title: 'Hello',
      body: 'This is my first time!',
      userId: 1,
    }),  
  });
  const response = await apiPromise;

  // {
  //   headers: { 'Content-type': 'application/json; charset=UTF-8' },
  //   body: '{"title":"Hello","body":"This is my first time!","userId":1}',
  //   id: 11
  // }
  console.log(response.data);
})();

例4:Vue/TypeScript での Hello world(Promise.prototype.then())

<template>
  <div>
    <div v-show="message">{{ message }}</div>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import axios from 'axios';

@Component
export default class Hello extends Vue {
  private message = "";

  mounted() {
    axios.get('https://jsonplaceholder.typicode.com/users')
    .then(response => {
      for (const user of response.data) {
        console.log(user);
      }
    })
    .catch((ex) => {
      if (ex.response !== undefined) {
        console.error(ex.response.data.error)
      }
    })
    this.message = 'See your console.log() <f12>';
  }
}
</script>

例5:Vue/TypeScript での リスト表示

<template>
  <div class="home">
    <v-card
      class="mx-auto"
      max-width="500"
    >
      <v-toolbar
        color="pink"
        dark
      >
        <v-app-bar-nav-icon></v-app-bar-nav-icon>

        <v-toolbar-title>Inbox</v-toolbar-title>

        <v-spacer></v-spacer>

        <v-btn icon>
          <v-icon>mdi-magnify</v-icon>
        </v-btn>

        <v-btn icon>
          <v-icon>mdi-checkbox-marked-circle</v-icon>
        </v-btn>
      </v-toolbar>

      <v-list two-line>
        <v-list-item-group
          v-model="selected"
          active-class="pink--text"
          multiple
        >
          <template v-for="(item, index) in items">
            <v-list-item :key="item.title">
              <template v-slot:default="{ active }">
                <v-list-item-content>
                  <v-list-item-title v-text="item.id"></v-list-item-title>

                  <v-list-item-subtitle
                    class="text--primary"
                    v-text="item.headline"
                  ></v-list-item-subtitle>

                  <v-list-item-subtitle v-text="item.name"></v-list-item-subtitle>
                </v-list-item-content>

                <v-list-item-action>
                  <v-list-item-action-text v-text="item.email"></v-list-item-action-text>

                  <v-icon
                    v-if="!active"
                    color="grey lighten-1"
                  >
                    mdi-star-outline
                  </v-icon>

                  <v-icon
                    v-else
                    color="yellow darken-3"
                  >
                    mdi-star
                  </v-icon>
                </v-list-item-action>
              </template>
            </v-list-item>

            <v-divider
              v-if="index < items.length - 1"
              :key="index"
            ></v-divider>
          </template>
        </v-list-item-group>
      </v-list>
    </v-card>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import axios, { AxiosError } from 'axios';

@Component
export default class Demo2 extends Vue {
  private items: Array<any> = new Array<any>();

  created() {
    axios.get('https://jsonplaceholder.typicode.com/users')
      .then((response) => {
        // console.info(response);
        console.info('Response OK');
        this.items = response.data;
      })
      .catch((ex: AxiosError) => {
        // console.error(ex);
        console.error('Error...');
      });
  }
}
</script>

参考文献

https://reffect.co.jp/vue/vue-axios-learn
https://www.willstyle.co.jp/blog/2751/
https://qiita.com/keyakko/items/ec536545d2faa9cabc84
https://tositeru.github.io/Notebook/js/axios.html

関連記事

axios で リクエストに対してキャンセルするには
https://dk521123.hatenablog.com/entry/2021/03/24/110355
非同期処理 ~ async/await, Promise ~
https://dk521123.hatenablog.com/entry/2021/01/16/202822
JS単体試験ツール Jest ~ Mock編 ~
https://dk521123.hatenablog.com/entry/2021/01/26/215558
Jestを使った Vue / TypeScript の単体試験 ~ axios 編 ~
https://dk521123.hatenablog.com/entry/2021/01/16/202822