Axiosとは?JavaScriptでHTTP通信を簡潔に実装する方法を解説
Webアプリケーション開発では、画面に表示するデータを取得したり、フォーム入力をサーバーへ送信したり、ユーザー情報を更新したりするために、HTTP通信を実装する場面が頻繁にあります。JavaScriptには標準機能としてフェッチAPIがありますが、実務ではリクエスト設定、エラーハンドリング、認証ヘッダー、共通設定、レスポンス変換などを整理する必要があり、単純な通信処理だけでは済まないことも少なくありません。
Axiosは、こうしたHTTP通信を簡潔に実装するためのJavaScriptライブラリです。プロミスベースで非同期処理を書けるため、thenやasync/awaitと組み合わせて扱いやすく、ブラウザとNode.jsの両方で利用できます。GETやPOSTのような基本的な通信だけでなく、PUT、PATCH、DELETE、ヘッダー設定、インターセプター、共通エラーハンドリングなど、実務で必要になりやすい機能をまとめて扱える点が特徴です。
特にReactやTypeScriptを使った開発では、API通信をコンポーネント内に直接書き続けると、処理が散らばって保守しにくくなります。Axiosを適切に使い、インスタンス化やサービス層への分離、型安全なレスポンス定義、インターセプターによる認証処理を整えることで、アプリケーション全体の通信処理を整理しやすくなります。本記事では、Axiosの基本から実務での活用方法、Fetch APIとの違い、ベストプラクティスまでを体系的に解説します。
1. Axiosとは
Axiosとは、JavaScriptでHTTPリクエストを送信するためのプロミスベースのHTTPクライアントです。ブラウザではサーバーAPIとの通信に利用でき、Node.js環境では外部APIや社内APIへリクエストを送るためにも利用できます。GET、POST、PUT、PATCH、DELETEなどのHTTPメソッドを分かりやすいメソッド名で実行できるため、API通信コードを簡潔に書けます。
Axiosは、単に通信を送るだけのライブラリではありません。リクエスト前にヘッダーを付与する、レスポンスを受け取った後に共通処理を行う、エラーを一元的に処理する、レスポンスの型をTypeScriptで定義するなど、実務で必要になる周辺機能をまとめて扱いやすい点が特徴です。そのため、小規模なAPI通信から中規模・大規模なフロントエンドアプリケーションまで幅広く利用されています。
1.1 Axiosが開発された背景
Axiosが利用されるようになった背景には、JavaScriptでHTTP通信を簡潔に扱いたいというニーズがあります。かつてブラウザで通信処理を書く場合、XMLHttpRequestを直接扱う必要があり、リクエスト作成、状態監視、レスポンス処理、エラー処理などのコードが複雑になりがちでした。アプリケーションが大きくなるほど、毎回同じような通信処理を書くことは保守性を下げる原因になります。
Axiosは、こうした通信処理をよりシンプルに書けるようにするために普及しました。プロミスベースのAPIを提供することで、非同期処理を分かりやすく書けるようになり、async/awaitとも自然に組み合わせられます。また、ブラウザとNode.jsで同じような書き方ができるため、フロントエンドとバックエンドの両方でHTTP通信を統一的に扱いやすいという利点があります。
1.2 Axiosが現在も利用される理由
現在はフェッチAPIが標準機能として広く利用できるようになっていますが、それでもAxiosは多くのプロジェクトで使われています。その理由は、通信処理に必要な実務向け機能がまとまっているからです。たとえば、リクエストやレスポンスのインターセプター、JSONデータの扱いやすさ、タイムアウト設定、HTTPステータスに応じたエラーハンドリング、共通設定を持つインスタンス作成などは、API通信を整理するうえで便利です。
また、既存プロジェクトでAxiosが採用されているケースも多く、学習コストが低いことも継続利用される理由です。フェッチAPIでも同じようなことは実装できますが、共通処理やエラー処理を自前で整える必要があります。Axiosを使うことで、API通信の書き方を統一し、開発者ごとの実装差を減らしやすくなります。
2. Axiosの主な特徴
Axiosの主な特徴は、プロミスベースで非同期処理を扱えること、ブラウザとNode.jsの両方で利用できること、HTTPリクエストを簡潔に記述できること、レスポンスデータを扱いやすい形で処理できることです。これらの特徴により、AxiosはAPI通信を中心とするWebアプリケーション開発で利用しやすいライブラリになっています。
さらに、Axiosにはインターセプターやインスタンス作成など、通信処理を共通化するための機能があります。たとえば、すべてのAPIリクエストに認証トークンを付与する、レスポンスエラーを共通処理する、APIのベースURLを一箇所で管理する、といった設計ができます。通信処理が増えるほど、こうした共通化の価値は大きくなります。
2.1 Promiseベースで非同期処理を実装できる
Axiosはプロミスベースで動作するため、非同期処理を扱いやすくなっています。API通信はサーバーからレスポンスが返るまで待つ必要があるため、同期的に処理することはできません。Axiosでは、リクエスト結果をプロミスとして受け取り、thenやcatch、またはasync/awaitを使って処理できます。
実務では、async/awaitと組み合わせる書き方がよく使われます。これにより、非同期処理でありながら、上から順に読めるようなコードを書けます。特に、データ取得後に状態を更新する処理や、送信後に画面遷移する処理では、async/awaitを使うことで可読性を高めやすくなります。
import axios from 'axios';
async function fetchUsers() {
const response = await axios.get('/api/users');
return response.data;
}
2.2 ブラウザとNode.jsの両方で利用できる
Axiosは、ブラウザとNode.jsの両方で利用できます。ブラウザでは、フロントエンドアプリケーションからサーバーAPIへ通信するために使われます。Node.jsでは、サーバー側から外部APIへリクエストを送る場合や、バックエンド間通信を行う場合に利用できます。同じような記法で両環境に対応できる点は、Axiosの大きな特徴です。
この特徴により、フロントエンドとバックエンドの両方でJavaScriptやTypeScriptを使うプロジェクトでは、通信処理の考え方を統一しやすくなります。もちろん、ブラウザとNode.jsでは内部的な通信の仕組みや制約が異なるため、完全に同じ感覚で扱えるわけではありませんが、APIとしては一貫した書き方ができるため、学習コストを抑えやすくなります。
2.3 HTTPリクエストを簡潔に記述できる
Axiosでは、axios.get()、axios.post()、axios.put()、axios.patch()、axios.delete()のように、HTTPメソッドに対応した関数を使ってリクエストを送信できます。これにより、どの種類の通信を行っているのかがコードから読み取りやすくなります。API通信の処理を短く書けるため、実装の見通しも良くなります。
たとえば、ユーザー一覧を取得する処理はGET、ユーザーを新規作成する処理はPOST、ユーザー情報を更新する処理はPUTやPATCH、削除する処理はDELETEというように、HTTPメソッドの役割に合わせてコードを書けます。通信処理がREST APIの設計と対応しやすいため、フロントエンドとバックエンドの連携も整理しやすくなります。
2.4 レスポンスデータを自動変換できる
Axiosは、レスポンスとして受け取ったJSONデータを扱いやすい形に変換してくれます。一般的なAPIではJSON形式でデータを返すことが多く、Axiosではresponse.dataからレスポンスボディを取得できます。フェッチAPIでは、レスポンスに対してjson()を呼び出して変換する必要がありますが、Axiosではこの処理がシンプルになります。
この自動変換により、API通信後の処理を短く書けます。たとえば、ユーザー一覧を取得して画面に表示する場合、response.dataをそのまま状態管理に渡すことができます。ただし、APIレスポンスの型や中身が正しいかどうかは別問題です。TypeScriptやZodなどを組み合わせてレスポンスの型や構造を確認すると、より安全な通信処理を構築できます。
3. Axiosのインストール方法
Axiosは、npmやyarnを使って簡単に導入できます。React、Vue、Next.js、Node.js、TypeScriptなど、多くのJavaScript環境で利用できます。基本的にはパッケージをインストールし、必要なファイルでaxiosをインポートして使います。導入自体は簡単ですが、実務ではどのように通信処理を管理するかも重要です。
小規模なプロジェクトでは、コンポーネント内で直接Axiosを呼び出すこともあります。しかし、プロジェクトが大きくなると、API通信処理をサービス層やAPIクライアントとして分離する方が保守しやすくなります。インストール後すぐに使い始めるだけでなく、共通設定やインスタンス化の方針も合わせて考えるとよいでしょう。
3.1 npmでAxiosを導入する方法
npmでAxiosを導入する場合は、プロジェクトのルートディレクトリでnpm install axiosを実行します。これにより、Axiosが依存関係として追加され、JavaScriptやTypeScriptのファイルから利用できるようになります。npmを使っているプロジェクトでは、最も一般的な導入方法です。
インストール後は、import axios from 'axios'として読み込み、GETやPOSTなどの通信処理を実装します。最初は直接axios.get()を呼び出しても構いませんが、実務ではAPIのベースURLや共通ヘッダーを設定したAxiosインスタンスを作成しておくと、後から通信処理を整理しやすくなります。
npm install axios
3.2 yarnでAxiosを導入する方法
yarnを利用しているプロジェクトでは、yarn add axiosでAxiosを導入できます。npmと同じように、依存関係としてAxiosが追加され、コード内からインポートして利用できます。チーム開発では、npmとyarnを混在させるとロックファイルが複数になり、依存関係の管理が複雑になるため、プロジェクトで採用しているパッケージ管理ツールに統一することが大切です。
yarnで導入した場合も、基本的な使い方は変わりません。ReactやNext.jsでは、API通信を行うファイルやカスタムフックからAxiosを利用できます。複数のAPIを扱う場合は、通信処理をまとめるディレクトリを作り、APIごとに関数を分けて管理すると保守しやすくなります。
yarn add axios
3.3 TypeScriptでAxiosを利用する方法
TypeScriptでAxiosを利用する場合も、基本的にはAxios本体をインストールすれば利用できます。AxiosはTypeScriptの型定義を含んでいるため、レスポンスやエラーの型を扱いやすくなっています。APIレスポンスに型を付けることで、取得したデータを安全に利用しやすくなります。
たとえば、ユーザー一覧を取得するAPIであれば、User型を定義し、axios.get<User[]>('/api/users')のようにジェネリクスを指定できます。これにより、response.dataがユーザー配列として推論され、後続処理で補完や型チェックを活用できます。ただし、TypeScriptの型は実行時のデータ検証ではないため、外部APIのレスポンスが本当に型どおりかを保証したい場合は、別途バリデーションも検討する必要があります。
import axios from 'axios';
type User = {
id: string;
name: string;
};
const response = await axios.get<User[]>('/api/users');
4. Axiosの基本的な使い方
Axiosの基本的な使い方は、HTTPメソッドに対応した関数を呼び出し、レスポンスを受け取って処理することです。GETでデータを取得し、POSTでデータを送信し、PUTやPATCHで更新し、DELETEで削除するという流れは、多くのAPI通信で共通しています。Axiosではこれらの処理をシンプルなメソッド名で実装できます。
また、Axiosはプロミスベースであるため、async/awaitと組み合わせることで、非同期通信を読みやすく書けます。通信処理はエラーが発生する可能性が高いため、実務ではtry-catchを使ってエラーハンドリングもセットで実装することが重要です。基本的な書き方を理解したうえで、共通化や型付けを進めるとよいでしょう。
4.1 GETリクエストを送信する方法
GETリクエストは、サーバーからデータを取得するために使います。Axiosでは、axios.get('/api/users')のように書くことでGETリクエストを送信できます。取得したレスポンスの本文は、通常response.dataから参照します。ユーザー一覧、商品一覧、記事一覧、詳細データなどを取得する場面でよく使われます。
GETリクエストでは、必要に応じてクエリパラメータを指定します。たとえば、検索キーワードやページ番号、並び替え条件をサーバーに送る場合です。Axiosでは、paramsオプションを使ってクエリパラメータを指定できるため、URL文字列を手動で組み立てるより安全で読みやすくなります。
const response = await axios.get('/api/users');
console.log(response.data);
4.2 POSTリクエストを送信する方法
POSTリクエストは、サーバーへ新しいデータを送信するために使います。ユーザー登録、問い合わせ送信、商品作成、コメント投稿など、データを新規作成する処理でよく利用されます。Axiosでは、axios.post('/api/users', data)のように、URLと送信データを指定して実行します。
POSTでは、送信するデータの形式にも注意が必要です。一般的なAPIではJSON形式で送信することが多く、Axiosはオブジェクトを渡すとJSONとして扱いやすい形で送信できます。ただし、ファイルアップロードやフォーム送信では、フォームデータを使う必要があります。APIの仕様に合わせて送信形式を選ぶことが重要です。
const response = await axios.post('/api/users', {
name: 'Taro',
email: '[email protected]',
});
4.3 async/awaitと組み合わせる方法
Axiosはプロミスを返すため、async/awaitと自然に組み合わせられます。await axios.get()のように書くことで、レスポンスが返るまで待ち、その後の処理を続けられます。これにより、非同期処理でありながら、同期処理に近い読みやすいコードを書けます。
実務では、async/awaitとtry-catchをセットで使うことが一般的です。API通信はネットワークエラー、認証エラー、サーバーエラー、バリデーションエラーなどが発生する可能性があります。エラーが発生した場合に画面へメッセージを表示したり、ログイン画面へ遷移したりするためには、適切なエラーハンドリングが必要です。
async function createUser() {
try {
const response = await axios.post('/api/users', {
name: 'Taro',
});
return response.data;
} catch (error) {
console.error('ユーザー作成に失敗しました', error);
}
}
5. AxiosでGETリクエストを実装する方法
GETリクエストは、APIからデータを取得するための基本的な通信方法です。Webアプリケーションでは、一覧表示、詳細表示、検索結果、マスターデータ取得など、多くの場面でGETリクエストを利用します。Axiosを使うと、GETリクエストを短く分かりやすいコードで実装できます。
GETリクエストでは、URLだけでなく、クエリパラメータやヘッダー、タイムアウトなどを設定することもあります。たとえば、検索キーワードを送信する場合や、認証が必要なAPIからデータを取得する場合です。Axiosの設定オブジェクトを使うことで、こうした条件を整理して記述できます。
5.1 データ取得の基本
データ取得の基本は、axios.get()にAPIのURLを指定し、レスポンスのdataを利用することです。たとえば、ユーザー一覧を取得する場合、axios.get('/api/users')を実行し、返ってきた配列を画面表示に使います。Reactでは、取得したデータを状態に保存して一覧表示することが多いです。
GETリクエストは読み取り専用の通信として扱われることが一般的です。そのため、サーバー側のデータを変更する処理には使わず、取得専用として利用します。API設計において、GETは安全な取得処理、POSTやPUTは変更処理という役割を分けることで、フロントエンド側の実装も分かりやすくなります。
const response = await axios.get('/api/articles');
const articles = response.data;
5.2 クエリパラメータを送信する方法
クエリパラメータを送信するには、Axiosのparamsオプションを使います。たとえば、検索キーワード、ページ番号、表示件数、並び順などをAPIへ渡したい場合に利用します。URL文字列を手動で連結することもできますが、paramsを使う方が可読性が高く、パラメータ管理もしやすくなります。
たとえば、/api/users?page=1&keyword=taroのようなURLを作りたい場合、params: { page: 1, keyword: 'taro' }と指定します。これにより、検索条件がオブジェクトとして整理され、後から条件を追加・変更しやすくなります。検索画面や一覧画面では、クエリパラメータの管理が重要になります。
const response = await axios.get('/api/users', {
params: {
page: 1,
keyword: 'taro',
},
});
5.3 APIレスポンスを処理する方法
Axiosのレスポンスには、data、status、headersなどの情報が含まれます。通常、画面表示に使うデータはresponse.dataに入っていますが、HTTPステータスやレスポンスヘッダーを確認したい場合もあります。たとえば、ページネーション情報がヘッダーに含まれるAPIでは、headersも参照する必要があります。
APIレスポンスを処理する際は、レスポンス形式をプロジェクト内で統一しておくと便利です。たとえば、すべてのAPIが{ data, message, errors }のような形式を返す場合、フロントエンド側でも共通処理を作りやすくなります。Axiosを使う場合でも、APIレスポンス設計が整理されているかどうかが、実装のしやすさに大きく影響します。
6. AxiosでPOSTリクエストを実装する方法
POSTリクエストは、サーバーへデータを送信し、新しいリソースを作成するために使われます。ユーザー登録、ログイン、記事投稿、注文作成、問い合わせ送信など、Webアプリケーションの多くの操作で利用されます。Axiosでは、axios.post()を使うことで、送信データを分かりやすく指定できます。
POSTリクエストでは、送信するデータ形式が重要です。多くのAPIではJSON形式を使いますが、ファイルアップロードや複数のフォーム項目を送る場合はフォームデータを使うことがあります。また、認証が必要なAPIでは、ヘッダーにトークンを付与する必要があります。POST処理はデータ変更を伴うため、成功時と失敗時の処理も明確に設計することが重要です。
6.1 JSONデータを送信する方法
JSONデータを送信する場合は、axios.post()の第2引数にオブジェクトを渡します。Axiosは、一般的な設定ではこのオブジェクトをJSONとして送信できます。ユーザー登録や記事作成のように、構造化されたデータをAPIへ送る場合に使われます。
JSON送信では、送信前にデータのバリデーションを行うことが重要です。フォーム入力をそのまま送信すると、空文字や不正な形式の値がサーバーに届く可能性があります。フロントエンド側で入力チェックを行い、サーバー側でも再度検証することで、より安全なAPI処理を実現できます。
await axios.post('/api/articles', {
title: 'Axiosの使い方',
body: '本文です',
});
6.2 フォームデータを送信する方法
フォームデータを送信する場合は、FormDataを使います。特に、画像やPDFなどのファイルをアップロードする場合には、JSONではなくフォームデータを利用することが一般的です。Axiosでは、FormDataオブジェクトをPOSTの第2引数に渡すことで送信できます。
ファイルアップロードでは、通常のJSON送信よりもエラーハンドリングや進捗管理が重要になる場合があります。ファイルサイズ制限、拡張子チェック、アップロード失敗時の再試行、送信中のローディング表示などを設計しておくと、ユーザー体験を改善できます。Axiosはフォームデータ送信にも対応しやすいため、アップロード機能でも利用しやすいです。
const formData = new FormData();
formData.append('file', file);
formData.append('title', 'プロフィール画像');
await axios.post('/api/upload', formData);
6.3 API登録処理で活用する方法
API登録処理では、POSTリクエストを使って新しいデータをサーバーに作成します。たとえば、ユーザー登録では名前、メールアドレス、パスワードを送信し、記事投稿ではタイトルや本文を送信します。登録処理では、送信前の入力検証、送信中のボタン無効化、成功時の画面遷移、失敗時のエラーメッセージ表示を組み合わせることが重要です。
Axiosを使う場合、登録処理をコンポーネント内に直接書くより、createUserやcreateArticleのようなAPI関数として分離すると保守しやすくなります。フォーム側はAPI関数を呼び出すだけにし、通信の詳細はサービス層に隠すことで、画面ロジックと通信ロジックを分けられます。これは中規模以上のReact開発で特に有効です。
7. AxiosでPUT・PATCH・DELETEを利用する方法
Axiosでは、GETやPOSTだけでなく、PUT、PATCH、DELETEリクエストも簡単に実装できます。これらは、既存データの更新や削除に使われるHTTPメソッドです。REST APIを利用するアプリケーションでは、作成はPOST、全体更新はPUT、部分更新はPATCH、削除はDELETEというように役割を分けることが一般的です。
これらのメソッドを正しく使い分けることで、API通信の意図が明確になります。たとえば、ユーザー情報全体を置き換える処理と、名前だけを変更する処理では、意味が異なります。フロントエンド側でも、どの操作がどのHTTPメソッドに対応するのかを理解しておくことが重要です。
7.1 PUTリクエスト活用法
PUTリクエストは、既存リソースを更新するために使われます。一般的には、対象リソース全体を置き換える意味で使われることが多いです。たとえば、ユーザー情報の全項目を更新する場合や、記事データ全体を保存し直す場合に利用されます。Axiosでは、axios.put('/api/users/1', data)のように実装できます。
PUTを使う場合は、サーバー側のAPI仕様を確認することが重要です。APIによっては、PUTでも部分更新を許可している場合がありますが、一般的な考え方としては全体更新に近い意味を持ちます。フロントエンド側では、どの項目を送る必要があるのかを明確にし、不足項目による意図しない上書きを防ぐ必要があります。
await axios.put('/api/users/1', {
name: 'Taro',
email: '[email protected]',
});
7.2 PATCHリクエスト活用法
PATCHリクエストは、既存リソースの一部を更新するために使われます。たとえば、ユーザー名だけを変更する、記事の公開状態だけを変更する、タスクの完了状態だけを更新する、といった処理に向いています。Axiosでは、axios.patch()を使って簡単に実装できます。
PATCHは、必要な項目だけを送信できるため、更新処理を軽量にしやすいメリットがあります。ただし、どの項目を部分更新できるのか、送られなかった項目は変更されないのか、nullを送った場合は削除扱いになるのかなど、API仕様を明確にする必要があります。部分更新は便利ですが、仕様が曖昧だと不具合につながりやすいです。
await axios.patch('/api/users/1', {
name: 'New Name',
});
7.3 DELETEリクエスト活用法
DELETEリクエストは、既存リソースを削除するために使われます。たとえば、記事削除、コメント削除、ユーザー削除、カート内商品の削除などで利用されます。Axiosでは、axios.delete('/api/articles/1')のように対象URLを指定して実行します。
削除処理では、誤操作を防ぐための確認ダイアログや、削除後の画面更新が重要になります。また、論理削除なのか物理削除なのか、削除後に復元できるのかもAPI設計に関わります。フロントエンド側では、DELETEリクエスト成功後に一覧から対象データを取り除く、再取得する、通知を表示するなどの処理を組み合わせることが一般的です。
await axios.delete('/api/articles/1');
8. AxiosでHTTPヘッダーを設定する方法
HTTPヘッダーは、リクエストやレスポンスに付加される追加情報です。Axiosでは、個別リクエストごとにヘッダーを設定することも、Axiosインスタンスに共通ヘッダーを設定することもできます。認証トークン、コンテンツタイプ、言語設定、APIキーなどを送信する場合に利用されます。
ヘッダー設定は、API認証やセキュリティに関わる重要な処理です。特に、Authorizationヘッダーにトークンを付与する処理は、多くのWebアプリケーションで必要になります。ただし、トークンの保存場所や更新方法を誤るとセキュリティリスクになるため、Axiosの設定だけでなく、認証設計全体を考える必要があります。
8.1 Authorizationヘッダーを追加する方法
Authorizationヘッダーは、認証が必要なAPIへアクセスする際によく使われます。たとえば、ログイン後に発行されたアクセストークンをBearer形式で送信する場合、headersオプションにAuthorizationを指定します。これにより、サーバー側はリクエストしたユーザーを認証できます。
個別リクエストにヘッダーを設定する方法は簡単ですが、すべてのAPIに毎回同じ設定を書くと重複が増えます。そのため、認証が必要なAPIが多い場合は、Axiosインスタンスやリクエストインターセプターを使って共通化する方が保守しやすくなります。
await axios.get('/api/me', {
headers: {
Authorization: `Bearer ${token}`,
},
});
8.2 共通ヘッダーを設定する方法
共通ヘッダーを設定するには、Axiosインスタンスを作成し、そのインスタンスにヘッダー設定を持たせます。たとえば、すべてのAPIリクエストでJSONを扱う場合や、共通のAPIキーを付与する場合に便利です。インスタンス化することで、API通信の設定を一箇所にまとめられます。
共通ヘッダーを設定する場合は、すべてのリクエストに本当に必要なヘッダーかどうかを確認することが重要です。不要なヘッダーを送ると、セキュリティやキャッシュ、CORS設定に影響する場合があります。認証が必要なAPIと不要なAPIを分けたい場合は、認証用インスタンスと公開API用インスタンスを分ける設計も有効です。
const apiClient = axios.create({
baseURL: '/api',
headers: {
'Content-Type': 'application/json',
},
});
8.3 API認証で活用する方法
API認証では、アクセストークンやAPIキーをリクエストに付与するためにヘッダーを使います。Axiosでは、ヘッダー設定をインターセプターと組み合わせることで、リクエスト送信前に自動的にトークンを付与できます。これにより、各API関数で毎回Authorizationヘッダーを書く必要がなくなります。
ただし、認証トークンの扱いには注意が必要です。トークンをどこに保存するか、期限切れ時にどう更新するか、ログアウト時にどう削除するかを設計する必要があります。Axiosはヘッダー付与を簡単にしてくれますが、認証全体の安全性はアプリケーション設計に依存します。
9. Axiosインターセプター活用法
Axiosインターセプターとは、リクエストが送信される前、またはレスポンスが処理される前に、共通処理を差し込める仕組みです。たとえば、すべてのリクエストに認証トークンを追加する、レスポンスエラーを共通処理する、ログを出力する、特定のステータスコードでログイン画面へ遷移する、といった用途で利用できます。
インターセプターを使うと、通信処理の共通化がしやすくなります。各API関数に同じようなヘッダー付与やエラー処理を書く必要がなくなり、コードの重複を減らせます。ただし、インターセプターに処理を詰め込みすぎると、通信の流れが見えにくくなるため、役割を明確にして設計することが重要です。
9.1 Request Interceptorとは
リクエストインターセプターとは、HTTPリクエストが送信される前に実行される処理です。代表的な使い方は、認証トークンの付与です。APIを呼び出すたびに現在のアクセストークンを取得し、Authorizationヘッダーに追加することで、各API関数に認証処理を書かなくても済みます。
また、リクエスト前にログを出力したり、共通パラメータを付与したり、リクエスト設定を調整したりすることもできます。ただし、リクエストインターセプターで非同期処理を行う場合は、処理の遅延や失敗時の挙動に注意が必要です。認証トークン更新のような複雑な処理は、無限ループや競合が発生しないよう慎重に設計する必要があります。
apiClient.interceptors.request.use((config) => {
const token = getAccessToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
9.2 Response Interceptorとは
レスポンスインターセプターとは、サーバーからレスポンスを受け取った後、アプリケーション側の処理に渡す前に実行される処理です。成功レスポンスを加工したり、エラーレスポンスを共通処理したりできます。たとえば、APIレスポンスが常に{ data: ... }形式で返る場合、レスポンスインターセプターでdataだけを取り出す設計も可能です。
エラー処理では、401 Unauthorizedの場合にログイン画面へ遷移する、403 Forbiddenの場合に権限エラーを表示する、500番台のエラーでは共通通知を出す、といった処理をまとめられます。これにより、各API呼び出しで同じエラー処理を繰り返す必要がなくなります。ただし、画面ごとに異なるエラー表示が必要な場合は、共通処理と個別処理の責任範囲を分けることが重要です。
apiClient.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
redirectToLogin();
}
return Promise.reject(error);
}
);
9.3 認証トークン管理に活用する方法
Axiosインターセプターは、認証トークン管理でよく利用されます。リクエスト前にアクセストークンをヘッダーへ付与し、レスポンスで401エラーが返った場合にトークン更新やログアウト処理を行う、といった流れを実装できます。認証が必要なAPIが多いアプリケーションでは、インターセプターによる共通化が非常に有効です。
ただし、トークン更新処理は複雑になりやすい領域です。複数のAPIリクエストが同時に401を受け取った場合、更新処理が重複して走る可能性があります。また、更新に失敗した場合のログアウト処理や、リクエストの再実行方法も設計する必要があります。Axiosインターセプターは便利ですが、認証トークン管理では安全性と制御のしやすさを重視して設計することが重要です。
10. Axiosでエラーハンドリングを実装する方法
API通信では、さまざまなエラーが発生します。ネットワークエラー、サーバーエラー、認証エラー、権限エラー、入力バリデーションエラー、タイムアウトなどです。Axiosを使う場合、こうしたエラーを適切に分類し、ユーザーに分かりやすく伝えることが重要です。
エラーハンドリングを各コンポーネントでばらばらに実装すると、画面ごとに挙動が異なり、保守が難しくなります。そのため、APIエラーの形式を共通化し、必要に応じてインターセプターやサービス層で処理する設計が有効です。Axiosでは、try-catchやAxiosErrorを利用してエラー情報を扱えます。
10.1 try-catchで処理する方法
async/awaitとAxiosを組み合わせる場合、try-catchでエラーを処理するのが基本です。リクエストが成功すればtry内でレスポンスを受け取り、失敗すればcatchでエラーを処理します。これにより、通信失敗時に画面へメッセージを表示したり、処理を中断したりできます。
try-catchは分かりやすい方法ですが、すべてのAPI呼び出しで同じようなエラー処理を書くと重複が増えます。個別画面で必要な処理はcatchで行い、共通のログ出力や認証エラー処理はインターセプターや共通関数にまとめると、バランスの良い設計になります。
try {
const response = await axios.get('/api/users');
console.log(response.data);
} catch (error) {
console.error('データ取得に失敗しました', error);
}
10.2 AxiosErrorを利用する方法
TypeScriptでAxiosのエラーを扱う場合は、AxiosErrorを利用するとエラー情報にアクセスしやすくなります。Axiosのエラーには、サーバーからのレスポンス、ステータスコード、リクエスト情報などが含まれる場合があります。axios.isAxiosError(error)を使えば、エラーがAxios由来かどうかを判定できます。
AxiosErrorを利用すると、HTTPステータスコードに応じた分岐や、APIから返されたエラーメッセージの取得がしやすくなります。ただし、エラーの形はAPI設計によって異なるため、error.response?.dataの型をどう扱うかも考える必要があります。共通のエラーレスポンス型を定義しておくと、より安全に処理できます。
import axios from 'axios';
try {
await axios.get('/api/users');
} catch (error) {
if (axios.isAxiosError(error)) {
console.log(error.response?.status);
console.log(error.response?.data);
}
}
10.3 APIエラーを共通化する方法
APIエラーを共通化するには、サーバー側のエラーレスポンス形式を統一し、フロントエンド側でもそれに合わせたエラー処理を作ることが重要です。たとえば、すべてのAPIエラーを{ message, errors, code }のような形式で返すようにすれば、フロントエンド側で共通の表示処理を作りやすくなります。
Axios側では、インターセプターやAPIクライアント層でエラーを共通形式に変換する方法があります。これにより、コンポーネント側は通信ライブラリ固有のエラー構造を意識せず、アプリケーション共通のエラー型だけを扱えます。大規模なアプリケーションでは、エラー処理の共通化が保守性に大きく影響します。
11. AxiosとTypeScriptを組み合わせる方法
AxiosはTypeScriptと組み合わせて利用しやすいHTTPクライアントです。APIレスポンスに型を付けることで、取得したデータを安全に扱いやすくなります。特に、ReactやNext.jsのようなTypeScriptプロジェクトでは、API通信の型を明確にすることで、画面表示や状態管理のミスを減らせます。
ただし、TypeScriptの型は実行時のデータ検証ではありません。axios.get<User>()と書いても、実際にAPIから返ってきたデータが必ずUser型どおりであるとは限りません。そのため、外部APIや信頼できないデータを扱う場合は、Zodなどのバリデーションライブラリと組み合わせることも検討するとよいでしょう。
11.1 Axiosレスポンスに型を付与する方法
Axiosレスポンスに型を付与するには、axios.get<T>()のようにジェネリクスを指定します。たとえば、ユーザー情報を取得するAPIであれば、User型を定義し、axios.get<User>('/api/user')と書くことで、response.dataがUser型として扱われます。これにより、プロパティ名の補完や型チェックが効くようになります。
型を付けることで、画面側の実装ミスを減らせます。たとえば、存在しないプロパティを参照しようとするとTypeScriptがエラーを出してくれます。ただし、API仕様が変わった場合には型定義も更新する必要があります。API型を手動で管理する場合は、バックエンド仕様とのズレに注意が必要です。
type User = {
id: string;
name: string;
email: string;
};
const response = await axios.get<User>('/api/user');
const userName = response.data.name;
11.2 ジェネリクスを活用する方法
ジェネリクスを活用すると、複数のAPI関数で型安全な通信処理を作れます。たとえば、共通のGET関数を作り、呼び出し時にレスポンス型を指定する設計にすれば、APIごとに似た処理を繰り返さずに済みます。型を引数として渡すことで、汎用的でありながら型安全なAPIクライアントを作成できます。
ただし、共通化しすぎると、APIごとの違いが見えにくくなる場合があります。認証が必要なAPI、ページネーションがあるAPI、エラー形式が異なるAPIなど、通信の性質が異なる場合は、無理に一つの関数にまとめるより、用途に応じて分ける方が保守しやすいこともあります。ジェネリクスは便利ですが、設計の分かりやすさを優先することが重要です。
async function getApi<T>(url: string): Promise<T> {
const response = await apiClient.get<T>(url);
return response.data;
}
11.3 型安全なAPIクライアントを構築する方法
型安全なAPIクライアントを構築するには、APIごとのリクエスト型とレスポンス型を定義し、それに基づいて関数を作成します。たとえば、getUsers、createUser、updateUserのようにAPI関数を分け、それぞれの引数と戻り値に型を付けます。これにより、コンポーネント側は型安全な関数を呼び出すだけで通信できます。
この設計では、Axiosを直接コンポーネントから呼び出さないことがポイントです。通信の詳細をAPIクライアントに閉じ込めることで、URL変更、ヘッダー変更、エラー処理変更が必要になった場合も、修正箇所を限定できます。TypeScriptとAxiosを組み合わせる場合は、型定義だけでなく、通信処理の責任範囲も整理すると効果的です。
12. AxiosとReactを組み合わせる方法
ReactでAxiosを使う場合、コンポーネントの表示に必要なデータを取得したり、フォーム送信時にAPIへデータを送ったりする用途が中心になります。useEffect内でデータ取得を行う方法が基本ですが、実務ではカスタムフックや状態管理ライブラリと組み合わせて通信処理を整理することが多くなります。
Reactでは、通信状態を画面に反映することが重要です。データ取得中はローディングを表示し、取得成功時はデータを表示し、失敗時はエラーメッセージを表示する必要があります。Axios自体は通信を担当するライブラリであり、状態管理までは行わないため、React側で状態設計を行う必要があります。
12.1 useEffectでデータ取得する方法
Reactでデータ取得を行う基本的な方法は、useEffectの中でAxiosを呼び出すことです。コンポーネントが表示されたタイミングでAPIを呼び出し、取得したデータをuseStateで管理します。ユーザー一覧や記事一覧のように、画面表示時にデータを読み込む処理でよく使われます。
ただし、useEffect内で直接通信処理を書く場合は、コンポーネントが複雑になりやすい点に注意が必要です。ローディング状態、エラー状態、キャンセル処理、再取得処理などが増えると、表示ロジックと通信ロジックが混ざってしまいます。小規模な画面では問題ありませんが、処理が増える場合はカスタムフック化を検討するとよいでしょう。
useEffect(() => {
async function fetchUsers() {
const response = await axios.get('/api/users');
setUsers(response.data);
}
fetchUsers();
}, []);
12.2 カスタムフックで利用する方法
Axiosの通信処理をカスタムフックにまとめると、コンポーネントをすっきり保てます。たとえば、useUsersというフックを作り、その中でユーザー一覧の取得、ローディング状態、エラー状態を管理します。コンポーネント側は、フックから返されたデータと状態を使って表示するだけになります。
カスタムフック化することで、同じ通信処理を複数の画面で再利用しやすくなります。また、テストや保守もしやすくなります。ただし、データ取得やキャッシュ、再検証が複雑になる場合は、React QueryやSWRのようなデータ取得ライブラリを使う方が適している場合もあります。
12.3 状態管理ライブラリと連携する方法
Axiosは、状態管理ライブラリと組み合わせて利用できます。たとえば、取得したユーザー情報をグローバル状態に保存したり、ログインユーザー情報を状態管理に反映したりする場合です。Redux、Zustand、Jotai、Recoilなどを使っているプロジェクトでは、Axiosで取得したデータを状態として管理できます。
ただし、APIデータのキャッシュや再取得、ローディング管理、エラー管理をすべて状態管理ライブラリで自作すると複雑になる場合があります。そのような場合は、React QueryやSWRのようなサーバー状態管理に特化したライブラリとAxiosを組み合わせると、より効率的に実装できます。Axiosは通信を担当し、状態管理ライブラリはデータの保持や再取得を担当する、という役割分担が重要です。
13. AxiosとFetch APIの違い
AxiosとフェッチAPIは、どちらもHTTP通信を行うために利用されます。フェッチAPIはブラウザ標準の機能であり、追加ライブラリなしで利用できます。一方、Axiosは外部ライブラリですが、通信処理を便利にする機能が多く用意されています。どちらを使うべきかは、プロジェクトの規模、必要な機能、チームの方針によって変わります。
単純な通信だけであれば、フェッチAPIで十分な場合もあります。しかし、共通ヘッダー、インターセプター、エラー処理、タイムアウト、JSON処理、Node.jsとの共通利用などを重視する場合は、Axiosが便利です。重要なのは、どちらが常に優れているかではなく、要件に合った選択をすることです。
13.1 Axiosの特徴
Axiosの特徴は、API通信を簡潔に書けることと、実務向けの補助機能が多いことです。GETやPOSTなどのメソッドが分かりやすく用意されており、レスポンスデータもresponse.dataとして扱えます。また、インターセプターを使ってリクエストやレスポンスの共通処理を実装できる点も大きな特徴です。
エラーハンドリングにおいても、AxiosはHTTPステータスに応じたエラー処理を実装しやすいです。さらに、Axiosインスタンスを作成することで、ベースURLや共通ヘッダー、タイムアウトなどを一元管理できます。API通信が多いプロジェクトでは、こうした整理しやすさが大きなメリットになります。
13.2 Fetch APIの特徴
フェッチAPIは、ブラウザに標準搭載されているHTTP通信機能です。外部ライブラリを追加せずに使えるため、依存関係を増やしたくないプロジェクトでは有力な選択肢になります。基本的なGETやPOSTであれば、フェッチAPIでも十分に実装できます。
一方で、フェッチAPIではレスポンスのJSON変換を明示的に行う必要があり、HTTPエラーステータスを自動的に例外として扱うわけではありません。そのため、エラー処理や共通設定をきちんと整えるには、自前でラッパー関数を作ることが多くなります。標準機能であることは大きなメリットですが、実務向けの共通化は別途設計が必要です。
13.3 AxiosとFetch APIを比較する方法
AxiosとフェッチAPIを比較する際は、機能、依存関係、開発効率、保守性、チームの慣れを基準に考えるとよいでしょう。小規模なプロジェクトで通信処理が少ない場合は、フェッチAPIで十分なことがあります。一方、API通信が多く、認証やエラー処理を共通化したい場合は、Axiosの方が実装しやすい場合があります。
また、既存プロジェクトでどちらが使われているかも重要です。すでにAxiosで通信基盤が整っているなら、無理にフェッチAPIへ移行する必要はありません。逆に、新規プロジェクトで外部依存を減らしたい場合は、フェッチAPIをベースに共通ラッパーを作る選択もあります。プロジェクト全体の設計方針に合わせて選択することが大切です。
14. Axiosを利用するメリット
Axiosを利用するメリットは、開発効率を向上できること、エラーハンドリングを統一しやすいこと、API通信コードを整理しやすいことです。API通信は多くの画面で発生するため、書き方がばらばらになると保守が難しくなります。Axiosを使って共通設定やAPIクライアントを整えることで、通信処理を統一できます。
また、AxiosはTypeScriptやReactとも組み合わせやすく、レスポンス型を定義したり、カスタムフックで通信処理を再利用したりできます。単純な通信だけでなく、アプリケーション全体の通信基盤として設計しやすい点が、Axiosの実務上のメリットです。
14.1 開発効率を向上できる
Axiosを使うと、GETやPOSTなどのHTTP通信を短く分かりやすく書けます。レスポンスデータも扱いやすく、async/awaitと組み合わせることで非同期処理を読みやすく実装できます。API通信を素早く実装できることは、開発効率の向上につながります。
また、共通インスタンスやインターセプターを使えば、認証ヘッダーやベースURL、エラー処理を毎回書く必要がなくなります。同じような通信処理を繰り返し実装する手間が減るため、機能開発に集中しやすくなります。特にAPI数が多いアプリケーションでは、Axiosの共通化機能が効果を発揮します。
14.2 エラーハンドリングを統一できる
Axiosでは、通信エラーをtry-catchやインターセプターで処理できます。HTTPステータスに応じた共通処理を作ることで、画面ごとに異なるエラー処理が散らばるのを防げます。たとえば、401エラーではログイン画面へ遷移し、500番台のエラーでは共通メッセージを表示する、といった設計ができます。
エラーハンドリングの統一は、ユーザー体験にも関わります。ある画面では分かりやすいエラーが出るのに、別の画面では何も表示されない、という状態は避けるべきです。Axiosを使ってエラー処理を共通化すれば、アプリケーション全体で一貫したエラー表示を実現しやすくなります。
14.3 API通信コードを整理できる
Axiosを利用すると、API通信コードをサービス層やAPIクライアント層へ分離しやすくなります。たとえば、ユーザー関連APIはuserApi.ts、記事関連APIはarticleApi.tsのようにファイルを分け、コンポーネントからはそれらの関数を呼び出すだけにします。これにより、画面ロジックと通信ロジックを分離できます。
通信コードを整理することで、URL変更やレスポンス形式変更にも対応しやすくなります。コンポーネント内に直接Axios処理が散らばっていると、API仕様変更時に多くの画面を修正する必要があります。APIクライアント層にまとめておけば、修正箇所を限定でき、保守性を高められます。
15. Axios活用のベストプラクティス
Axiosを効果的に活用するには、Axiosインスタンスを作成し、API処理をサービス層へ分離し、インターセプターを適切に使い、TypeScriptで型安全な通信基盤を構築することが重要です。単にaxios.get()を各コンポーネントに書くだけでは、プロジェクトが大きくなるにつれて管理が難しくなります。
API通信はアプリケーション全体の基盤となるため、早い段階で設計方針を決めることが大切です。ベースURL、認証ヘッダー、エラー処理、レスポンス型、リトライ方針、タイムアウト、キャンセル処理などを整理しておくと、後から機能が増えても安定した通信基盤を維持しやすくなります。
15.1 Axiosインスタンスを作成する
Axiosインスタンスを作成すると、ベースURL、共通ヘッダー、タイムアウトなどを一箇所で管理できます。たとえば、apiClientというインスタンスを作成し、すべてのAPI通信でそれを使うようにすれば、設定の重複を減らせます。APIのベースURLが変わった場合も、インスタンス設定を修正するだけで対応できます。
また、認証が必要なAPIと不要なAPIでインスタンスを分けることもできます。公開API用、管理画面API用、外部API用など、用途ごとにインスタンスを分けることで、ヘッダーやエラー処理の責任範囲を明確にできます。Axiosインスタンスは、通信処理を整理するうえで基本となる設計です。
export const apiClient = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
15.2 API処理をサービス層へ分離する
API処理は、コンポーネント内に直接書くのではなく、サービス層やAPIクライアント層へ分離することが望ましいです。たとえば、getUsers、createUser、updateUser、deleteUserのような関数を用意し、コンポーネント側ではそれらを呼び出します。これにより、画面ロジックと通信ロジックを分けられます。
サービス層へ分離すると、API仕様変更への対応がしやすくなります。URLやレスポンス形式が変わった場合でも、API関数側を修正すれば、コンポーネント側への影響を抑えられます。また、テストもしやすくなり、通信処理の再利用性も高まります。中規模以上のアプリケーションでは、早い段階でサービス層を設計しておくことが重要です。
15.3 Interceptorsを活用する
インターセプターは、認証ヘッダーの付与やエラー処理の共通化に有効です。すべてのリクエストにアクセストークンを追加したい場合や、401エラーでログイン画面へ遷移したい場合など、共通処理を一箇所にまとめられます。通信処理が多いアプリケーションでは、インターセプターによってコードの重複を減らせます。
ただし、インターセプターに多くの責任を持たせすぎると、通信の流れが分かりにくくなります。ログ出力、認証、エラー変換、リトライ処理などをすべて詰め込むと、予期しない副作用が発生する可能性があります。インターセプターは共通処理に限定し、画面ごとの個別処理はコンポーネントやサービス層で扱うように分けることが大切です。
15.4 型安全な通信基盤を構築する
TypeScriptを使う場合は、Axiosレスポンスやリクエストデータに型を付け、型安全な通信基盤を構築することが重要です。APIごとにレスポンス型を定義し、Axiosのジェネリクスを使ってresponse.dataの型を明確にします。これにより、データの参照ミスやプロパティ名の間違いを開発時に検出しやすくなります。
さらに安全性を高めたい場合は、Zodなどのスキーマ検証ライブラリと組み合わせて、実行時にもレスポンスを検証する設計が有効です。TypeScriptの型は開発時の保証であり、実際のAPIレスポンスが型どおりであることまでは保証しません。型定義と実行時検証を組み合わせることで、より堅牢なAPI通信を実現できます。
おわりに
Axiosは、JavaScriptやTypeScriptでHTTP通信を簡潔に実装できるプロミスベースのHTTPクライアントです。GET、POST、PUT、PATCH、DELETEなどの基本的なHTTPメソッドを分かりやすく扱えるだけでなく、ヘッダー設定、インターセプター、エラーハンドリング、レスポンス変換、TypeScriptの型付けなど、実務で必要になりやすい機能も備えています。
特に、ReactやNext.jsなどのフロントエンド開発では、API通信処理が多くなりやすいため、Axiosインスタンスを作成し、サービス層へ分離し、インターセプターで共通処理を整理する設計が重要です。通信処理をコンポーネントに散らばらせず、APIクライアントとしてまとめることで、保守性と再利用性を高められます。
一方で、フェッチAPIも標準機能として広く利用できるため、すべてのプロジェクトで必ずAxiosが必要というわけではありません。小規模な通信であればフェッチAPIでも十分な場合があります。Axiosを導入するかどうかは、API通信の複雑さ、認証やエラー処理の共通化の必要性、TypeScriptとの連携、チームの開発方針を踏まえて判断するとよいでしょう。
EN
JP
KR