Axios とは?

Axios とは、自分のサーバーやサードパーティのサーバーに対して、データをフェッチするリクエストを行うことができる Promise ベースの HTTP ライブラリです。GETPOSTPUT/PATCHDELETE などのリクエストを、さまざまな方法で行うことができます。このチュートリアルでは、Axios とアプリケーションのやり取りのしくみ、Axios のリクエストと応答の構造、API に対するリクエストを作成する方法、CircleCI を使ったリクエストのテスト作成方法について説明します。

前提条件

このチュートリアルを進めるには、以下の準備が必要です。

Axios のしくみ

Axios では、NodeJS (サーバー側) と XMLHttpRequest (ブラウザー側) を使って HTTP リクエストを実行します。リクエストが成功すると、リクエストしたデータを含む応答が返されます。リクエストが失敗すると、エラーが返されます。リクエストと応答をインターセプトし、変換や編集することもできます。詳しくは、このチュートリアルの後半で説明します。

以下の図に、Axios とアプリケーションのやり取りのしくみを示します。

Axios の仕組み

Axios はまず、リクエストがブラウザーと NodeJS のどちら宛てかを判断します。判断に応じて適切な API リクエストの方法を決定し、応答を変換して、サーバーリクエストの送信元のクライアントに返します。

Axios のリクエストと応答の構成

Axios の基本リクエストは、必須オプションが url だけなので簡単に作成できます。送信するリクエストの種類に応じて、他のオプションも設定します。

以下にリクエストの例を示します。

const axios = require('axios');

const res = await axios.get(url, {
//We can add more configurations in this object
   params: {
  //This is one of the many options we can configure
   }
});

// This is the second configuration option
const res = await axios({
    method: 'get',
    url://Endpoint goes here,
    params:{

    }
});

Axios のメリットは、リクエストを非常に柔軟に構成できることです。Axios は、JavaScript のドット区切り表記での呼び出しに対応しています。また、オブジェクトリテラル形式で Axios のリクエストプロパティすべてを 1 つのオブジェクトにバンドルし、Axios リクエストの構成プロパティとして使用することもできます。

Axios では、リクエストの送信メソッドが、以下のように複数サポートされています。

  • request
  • get
  • delete
  • head
  • options
  • post
  • put
  • patch

次のコードスニペットでは、Axios を使ってサンプルの GET リクエストを Todos というサンプル API に送信しています。

axios({
  method: "get",
  url: "https://jsonplaceholder.typicode.com/todos",
  params: {
    _limit: 5,
  },
});

Axios の応答

Axios を使ってリクエストを送信したら、当然のことながら応答が返ってきます。以下のスニペットに、Axios の応答のデータ構造を示します。

{
  // `data` is the response that was provided by the server
  data: {},

  // `status` is the HTTP status code from the response
  status: 200,

  // `statusText` is the status message from the response
  statusText: 'OK',

  // `headers` are the HTTP headers that the server responded with
  headers: {},

  // `config` is the config that was provided to `axios` for the request
  config: {},

  // `request` is the request that generated the response
  request: {}
}

この応答には、以下の情報が含まれています。

  • リクエストしたデータが含まれるオブジェクト
  • サーバーから返されたステータスコード
  • statusText
  • 応答ヘッダー
  • Axios で設定された config オブジェクト
  • 応答の生成に使用された request オブジェクト

必要なデータに応じて、クライアント側アプリケーションでこの応答を処理します。

理論の説明ばかりで退屈でしょうか?それでは、次のセクションに進みましょう。Axios を使って HTTP リクエストを行う方法を具体的にご説明します。

Axios を使って HTTP リクエストを実行する

このセクションでは、GETPOST リクエストを実行し、同時リクエストを観察します。これには、JSONPlaceholder.という無料の “フェイク” API を利用します。

また、リクエストの実行と、Axios 内部での処理を把握するのに役立つアプリケーションも利用します。

作業を始める前に、チュートリアル用の GitHub リポジトリをクローンしてください。以下のコマンドを実行します。

git clone https://github.com/CIRCLECI-GWP/making-http-requests-axios

cd making-http-requests-axios

これで、このチュートリアルに必要なファイルが手に入りました。次に、依存関係として Axios と Jest の 2 つをインストールします。以下のコマンドを実行します。

npm install

ブラウザーで index.html ファイルを開き、Axios デモ用 Web ページを確認します。

 Axios デモ用 Web ページ

現時点では、ボタンには何の機能もありません。チュートリアルの後半で、それぞれの機能を作成します。

現状は、各リクエストに対応した 3 つのボタンがあります。ボタンをクリックしたら、Axios リクエストが実行され、ブラウザーにデータが返されて、応答が表示されるようにします。

クローンしたリポジトリの users.js ファイルに、Axios から返されたデータを表示するためのイベントリスナーがあります。このファイルには、リクエストを行うための関数も含まれています。まず、GET リクエストから始めましょう。

GET リクエストを実行する

今回は、以下のスニペットに示すリクエストを使用します。

axios
  .get("https://jsonplaceholder.typicode.com/users/1")
  .then((response) => {
    displayOutput(response);
  })
  .catch((err) => console.log(err));

このコードスニペットでは、まず、GET リクエストを JSON API に送信します。リクエストから promise が返されるので、応答の処理には .then() ブロックを使用しています。また、エラーが起きた場合にコンソールに記録するため、.catch() メソッドも必要です。

上記のコードスニペットを、users.js ファイルの getUser() 関数に追加して保存します。

その後、ブラウザーに移動し、[GET] ボタンをクリックしてみましょう。ボタンの下に、応答の詳細を示すコンテンツが表示されれば成功です。

Axios を使った GET リクエスト

スタイルや表示形式はあらかじめこちらで用意したものです。返される Axios の応答のセクションには、以下のものがあります。

  • Status セクション: 応答のステータスコードを表示します。今回はステータスコードが 200 であり、リクエストが成功したことを意味しています。

  • Headers セクション: サーバーからの応答に含まれるすべての HTTP ヘッダーが示されます。
  • Data セクション: リクエストでサーバーから返されたペイロード (情報) が示されます。この例の場合、user 1 に関するすべての情報です。
  • Config セクション: このリクエストで Axios に渡されたすべての設定が示されます。

リクエストからわかるように、Axios の動作は従来の fetch-API ライブラリと同様です。今回は GET リクエストだったので、リクエストと一緒に本文を渡す必要はありませんでした。次は、Axios を使用して POST リクエストを実行する方法について説明します。

POST リクエストを実行する

POST リクエストは、サーバーへのリクエストでデータを渡す点で GET リクエストとは少し異なります。ここでは、POST リクエストを使ってユーザーを作成し、そのユーザーに関する詳細情報を渡します。このリクエストのコードスニペットは、以下のとおりです。

axios
  .post("https://jsonplaceholder.typicode.com/users", {
    id: 11,
    name: "Tom Brady",
    username: "Brad",
    email: "tombrad@asd.com",
  })
  .then((response) => displayOutput(response))
  .catch((err) => console.log(err));

Axios を使った POST リクエストでは、リクエスト URL の後でオブジェクトを使用して、ユーザーの作成に必要なプロパティを定義します。処理が完了すると、サーバーから応答が返ります。作成したコードが機能することを確認するために、デモ用 Web ページに戻って、[POST] ボタンをクリックします。このコードスニペットは、users.js ファイルの postUser() 関数の一部です。

 Axios を使った POST リクエスト

POST リクエストでは、GET リクエストとは異なる以下のような応答が返されます。

  • Status セクション: リソースが作成されたことを意味する、ステータスコード 201 が示されます。この例では、新しいユーザーが作成されました。

  • Headers セクション: 送信したデータの長さが ‘content-length’ プロパティに示されます。また、location にデータの保存先が示されます。

  • Data セクション: サーバーに送信した情報が示されます。

  • Config セクション: リクエストと一緒に送信した設定が含まれます。具体的には、メソッドURL、送信したデータなどです。

POST リクエストで定義したデータと、サーバーから受信した応答 (リクエストにより作成されたリソース) が同じであることを確認してください。

このセクションでは、Axios リクエストを実行する方法、Axios リクエストの基本構造、想定される応答について説明しました。次のセクションでは、リクエストをインターセプトして、データがリクエストとして Axios に送信される前に検証する方法について説明します。

Axios のリクエストと応答のインターセプター

Axios でリクエストのインターセプトを行うタイミングは、then() コードブロックまたは catch() コードブロックの処理の前です。たとえば、クライアントを経由するすべてのリクエストに、有効な JWT トークンが含まれるかどうかを調べるとしましょう。このためには、リクエストインターセプターを設定して、サーバーに対して行われるすべての呼び出しに有効なトークンが含まれることを確認します。有効なトークンが呼び出しに含まれていない場合は、システムのユーザーをログインページに戻し、再び認証を受けさせます。簡潔に説明するため、現在のアプリケーション用のロガーを作成するという、やや単純なユースケースを使います。

このロガーは、リクエストが実行されたら、リクエストの URL とトリガーされた時間を記録します。以下のコードスニペットを使用します。

axios.interceptors.request.use(
  (config) => {
    const today = new Date();
    console.log(
      `${config.method.toUpperCase()} request sent to ${
        config.url
      } at ${today.getHours()} : ${today.getMinutes()}`
    );
    return config;
  },
  (error) => {
    console.log(error);
  }
);

Axios がリクエストの config セクションにアクセスして、リクエストのメソッド、URL、時間を表示します。このコードスニペットは、サンプルプロジェクトに含まれる users.js ファイルの interceptRequests() 関数の一部です。Axios インターセプターの動作を観察するために、Chrome ブラウザーコンソールを開いてください。[GET] ボタンをクリックして、API の最初のユーザーをフェッチするメソッドを実行しましょう。

Axios のリクエストインターセプター

インターセプターを機能させるには、jsonplaceholder API に対する同時リクエストとして呼び出す必要があります。このリクエストと応答を実装する Axios メソッドを、以下のコードスニペットに示します。

const concurrentRequests = () => {
  interceptRequests();
  axios
    .all([
      axios.get("https://jsonplaceholder.typicode.com/users?_limit=5"),
      axios.get("https://jsonplaceholder.typicode.com/albums?_limit=5"),
    ])
    .then(
      axios.spread((users, albums) => {
        displayOutput(albums);
      })
    )
    .catch((err) => console.log(err));
};

Chrome の DevTools の画像を見ると、リクエストを実行する際、Axios から API サーバーに送信する前に変更したり、検査したりできることがわかります。Axios インターセプターは、強力なだけではありません。リクエストや応答の動作の制御もできるのです。

インターセプターを使用して Axios のリクエストと応答を変更、検査する方法については以上です。おつかれさまでした!次は、Axios 実装に関するテストを作成しましょう。

Axios 実装をテストする

テストはアプリケーション開発に不可欠なプロセスです。テストを行うことにより、アプリケーションの動作が意図どおりであるかを確認し、常に高い品質を確保できます。チュートリアルの本セクションでは、Axios の node.js バージョンを使用します。依存関係をインストールしたときに Jest もインストールしたので、すぐにテストの作成を始められます。

ルートディレクトリに、app.jsapp.test.js という 2 つのファイルを作成します。app.js はリクエスト、app.test.js はテストに使用します。index.html ファイルの script セクションで定義されているブラウザー版の Axios ではなく、Node.js 版の Axios を使用するメソッドに確実にアクセスできるように、app.js ファイルを作り直す必要があります。

Node.js でリクエストを行うには、app.js ファイルで axios を使用します。このメソッドのリクエストの構造は、ブラウザー版のメソッドと同じです。

const axios = require("axios");

const getUser = async () => {
  const getResponse = await axios
    .get("https://jsonplaceholder.typicode.com/users/1")
    .then((response) => response)
    .catch((err) => console.log(err));
  return getResponse;

  module.export = { getUser };
};

このスニペットでは、まず、先ほどと同じ URL に対してリクエストを行い、応答を getResponse 変数に格納します。その後、この応答を必要とする他のメソッドや関数 (テストなど) がアクセスできるように、応答を返します。最後に、メソッドを、app.js ファイル外部でも使用できるようにエクスポートします。

次に、getUser メソッドに対するテストを作成するため、このメソッドを app.test.js テストファイルにインポートします。その後、以下に示すとおりにテストを記述します。

const { getUser, postUser, concurrentRequests } = require("./app.js");

describe("Axios requests suite", () => {
  test("should get a single user", async () => {
    const response = await getUser();
    expect(response).not.toBeNull();
    expect(response.status).toBe(200);
    expect(response.data.address.street).toContain("Kulas");
  });
}

このテストとサンプル応答オブジェクトを使用すると、Axios エンドポイントから呼び出されたデータが返され、API 呼び出しに成功したことを検証できます。ターミナルに移動して Jest コマンド npm test と入力し、このテストを実行しましょう。

 PASS  ./app.test.js
  Axios requests suite
    ✓ should get a single user (144 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.266 s, estimated 1 s
Ran all test suites.

成功です!次は、Axios を使った POST リクエストと同時リクエストを検証するためのテストも作成します。

テストファイルに以下のテストを追加します。

test("should post a new user", async () => {
  const response = await postUser();
  expect(response).not.toBeNull();
  expect(response.status).toBe(201);
  expect(response.data.username).toBe("Brad");
});

test("should make simultaneous axios requests", async () => {
  const response = await concurrentRequests();
  expect(response).not.toBeNull();
  expect(response.status).toBe(200);
});

完成したら、テストを再実行します。

npm run test

このテストも成功です!

npm run test

Axios リクエストの作成方法とテスト方法を学んだので、次は CI パイプラインを作成しましょう。CircleCI などの CI/CD ツールでは、変更によってパイプラインに問題が発生し、テストが失敗したときに、関係者に通知することができます。このようなフィードバックループを構築すると、ソフトウェア開発プロセスを順調に進めるうえで欠かせないインサイトと透明性が得られます。

CircleCI との統合

.circleci フォルダーを作成して、その中に config.yml ファイルを作成します。これが CircleCI の設定ファイルになります。このファイルに以下の設定を追加します。

version: 2.1
jobs:
  build:
    working_directory: ~/repo
    docker:
      - image: cimg/node:19.0.1
    steps:
      - checkout
      - restore_cache:
          key: dependency-cache-{{ checksum "package-lock.json" }}
      - run:
          name: install dependencies
          command: npm install
      - save_cache:
          key: dependency-cache-{{ checksum "package-lock.json" }}
          paths:
            - ./node_modules
      - run:
          name: Axios request tests
          command: npm run test
      - store_artifacts:
          path: ~/repo/axios-http-requests

この設定ファイルでは、working_directory で作業ディレクトリを定義した後、テストの実行に使用する Node イメージを指定しています。その後、プロジェクトに保存済みキャッシュがあるかどうかを確認します。キャッシュがある場合は、復元してから新しい依存関係をインストールします。新しい依存関係をインストールした後は、キャッシュを保存します。その後、テストを実行し、生成されたアーティファクトを保存します。

では、この設定ファイルを保存し、コミットして、自分の GitHub リポジトリに変更をプッシュしましょう。その後、CirclecI ダッシュボードにログインします。[Projects (プロジェクト)] セクションで、このチュートリアルの GitHub リポジトリを探します。今回は、making-http-requests-axios です。[Set Up Project (プロジェクトをセットアップ)] をクリックします。

プロジェクトのセットアップ

プロンプトが表示されたら、config.yml ファイルを配置したブランチの名前を入力します。このチュートリアルの場合、main ブランチです。その後、[Set up Project (プロジェクトをセットアップ)] をクリックします。

 プロジェクトの構成

パイプラインのビルドに成功しました。build ワークフローをクリックして詳細を確認しましょう。

build ワークフローを開く

詳細を確認したいステップをクリックします。たとえば、Axios request tests ステップを確認してみます。

Axios request tests ステップ

CircleCI では、GitHub リポジトリの main ブランチにプッシュが行われるたびに、変更を検出して、パイプラインを実行します。これにより、テストスイートを毎回確実に実行して、継続的インテグレーションプロセスを順調に進められます。

この Axios チュートリアルは作成しがいのあるものでした。みなさんのお役に立てたなら幸いです。


Waweru Mwaura 氏は品質工学を専門とするソフトウェア エンジニアです。生涯学習の実践者という顔も持ち、 Packt で執筆者を務めながら、工学や金融、テクノロジーの書籍を愛読しています。 Mwaura 氏の詳細な情報は、こちらの Web プロフィールをご覧ください。

さんの他の投稿を読む Waweru Mwaura