axios の使い方 — ブラウザ・Node.js両対応のHTTPクライアント
一言でいうと
axiosは、ブラウザとNode.jsの両方で動作するPromiseベースのHTTPクライアントです。REST APIとの通信を直感的かつ強力なAPIで実現し、リクエスト/レスポンスのインターセプター、自動JSON変換、タイムアウト制御など、実務で必要な機能を網羅しています。
どんな時に使う?
- 外部APIとの通信 — REST APIやGraphQLエンドポイントへのリクエスト送信(GET/POST/PUT/DELETEなど)
- サーバーサイド(Node.js)でのHTTP通信 — BFF(Backend for Frontend)やバッチ処理から外部サービスを呼び出す場合
- 認証トークンの一元管理 — インターセプターを使い、すべてのリクエストにAuthorizationヘッダーを自動付与したい場合
インストール
# npm
npm install axios
# yarn
yarn add axios
# pnpm
pnpm add axios
基本的な使い方
最も一般的なGETリクエストとPOSTリクエストの例です。
import axios from 'axios';
// 型定義
interface User {
id: number;
name: string;
email: string;
}
// GETリクエスト
async function fetchUser(userId: number): Promise<User> {
const response = await axios.get<User>(`https://api.example.com/users/${userId}`);
return response.data;
}
// POSTリクエスト
async function createUser(name: string, email: string): Promise<User> {
const response = await axios.post<User>('https://api.example.com/users', {
name,
email,
});
return response.data;
}
// 使用例
(async () => {
try {
const user = await fetchUser(1);
console.log(user.name);
const newUser = await createUser('田中太郎', 'tanaka@example.com');
console.log(newUser.id);
} catch (error) {
if (axios.isAxiosError(error)) {
console.error('APIエラー:', error.response?.status, error.message);
} else {
throw error;
}
}
})();
よく使うAPI
1. axios.create() — インスタンス生成
共通設定をまとめたカスタムインスタンスを作成します。実務ではほぼ必須です。
import axios from 'axios';
const apiClient = axios.create({
baseURL: 'https://api.example.com/v1',
timeout: 10000, // 10秒
headers: {
'Content-Type': 'application/json',
'X-Custom-Header': 'my-app',
},
});
// 以降はこのインスタンスを使う
const response = await apiClient.get<User[]>('/users');
2. インターセプター — リクエスト/レスポンスの横断処理
すべてのリクエストにトークンを付与し、レスポンスエラーを一元処理する典型パターンです。
// リクエストインターセプター
apiClient.interceptors.request.use(
(config) => {
const token = localStorage.getItem('accessToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// レスポンスインターセプター
apiClient.interceptors.response.use(
(response) => response,
(error) => {
if (axios.isAxiosError(error) && error.response?.status === 401) {
// トークン期限切れ → ログイン画面へリダイレクトなど
console.warn('認証エラー: 再ログインが必要です');
window.location.href = '/login';
}
return Promise.reject(error);
}
);
3. axios.all() / Promise.all() — 並列リクエスト
複数のAPIを同時に呼び出す場合です。
interface Post {
id: number;
title: string;
}
async function fetchDashboardData(userId: number) {
const [userRes, postsRes] = await Promise.all([
apiClient.get<User>(`/users/${userId}`),
apiClient.get<Post[]>(`/users/${userId}/posts`),
]);
return {
user: userRes.data,
posts: postsRes.data,
};
}
4. CancelToken / AbortController — リクエストのキャンセル
画面遷移時や検索入力中の不要なリクエストをキャンセルします。
// AbortController を使う方法(推奨)
async function fetchWithCancel(userId: number, signal: AbortSignal): Promise<User> {
const response = await apiClient.get<User>(`/users/${userId}`, {
signal,
});
return response.data;
}
// 使用例
const controller = new AbortController();
fetchWithCancel(1, controller.signal)
.then((user) => console.log(user))
.catch((error) => {
if (axios.isCancel(error)) {
console.log('リクエストがキャンセルされました');
}
});
// 任意のタイミングでキャンセル
controller.abort();
5. axios.isAxiosError() — 型安全なエラーハンドリング
axiosが投げたエラーかどうかを型ガード付きで判定します。
import axios, { AxiosError } from 'axios';
interface ApiErrorResponse {
code: string;
message: string;
}
async function safeRequest() {
try {
await apiClient.get('/protected-resource');
} catch (error: unknown) {
if (axios.isAxiosError<ApiErrorResponse>(error)) {
// error.response?.data は ApiErrorResponse 型として推論される
const status = error.response?.status;
const apiMessage = error.response?.data?.message;
console.error(`[${status}] ${apiMessage ?? error.message}`);
if (status === 404) {
console.error('リソースが見つかりません');
} else if (status && status >= 500) {
console.error('サーバーエラーが発生しました');
}
} else {
// ネットワーク障害など、axios以外のエラー
console.error('予期しないエラー:', error);
}
}
}
類似パッケージとの比較
| 特徴 | axios | fetch (標準API) | ky | got |
|---|---|---|---|---|
| 環境 | ブラウザ + Node.js | ブラウザ + Node.js (v18+) | ブラウザ中心 | Node.js専用 |
| JSON自動パース | ✅ | ❌(.json()が必要) | ✅ | ✅ |
| インターセプター | ✅ 組み込み | ❌ | ✅(hooks) | ✅(hooks) |
| リクエストキャンセル | ✅ | ✅(AbortController) | ✅ | ✅ |
| タイムアウト設定 | ✅ 簡単 | ❌(自前実装) | ✅ | ✅ |
| リトライ | ❌(別途実装) | ❌ | ✅ 組み込み | ✅ 組み込み |
| バンドルサイズ | ~13KB (gzip) | 0KB(ネイティブ) | ~3KB (gzip) | N/A |
| TypeScript対応 | ✅ 良好 | ✅ | ✅ | ✅ |
選定の目安:
- ブラウザ + Node.js で統一したい / インターセプターを多用する → axios
- 依存を減らしたい / シンプルな通信のみ → fetch(標準API)
- ブラウザ向けで軽量にしたい → ky
- Node.js専用でリトライ等が必要 → got
注意点・Tips
1. response.data を忘れない
axiosのレスポンスオブジェクトは { data, status, headers, config, ... } というラッパーです。APIの実データは response.data に入っています。
// ❌ よくあるミス
const users = await axios.get('/users'); // これはAxiosResponseオブジェクト
// ✅ 正しい
const { data: users } = await axios.get<User[]>('/users');
2. デフォルトのタイムアウトは無制限
axiosのデフォルトではタイムアウトが設定されていません(0 = 無制限)。本番環境では必ず設定してください。
const apiClient = axios.create({
baseURL: 'https://api.example.com',
timeout: 15000, // 15秒を推奨(要件に応じて調整)
});
3. CancelToken は非推奨
axios.CancelToken はレガシーAPIです。AbortController を使ってください(axios v0.22.0以降対応)。
4. フォームデータの送信
ファイルアップロード時は FormData を使います。axiosが自動で Content-Type: multipart/form-data を設定します。
async function uploadFile(file: File): Promise<void> {
const formData = new FormData();
formData.append('file', file);
formData.append('description', 'プロフィール画像');
await apiClient.post('/upload', formData);
// Content-Type は自動設定されるため、手動指定は不要
}
5. レスポンスのステータスコード判定
axiosはデフォルトで 2xx以外のステータスコードをエラーとして扱います。この挙動は validateStatus で変更可能です。
const response = await axios.get('/api/resource', {
validateStatus: (status) => status < 500, // 4xxはエラーにしない
});
まとめ
axiosは、ブラウザとNode.jsの両環境で一貫したHTTP通信を実現する、実績豊富なHTTPクライアントです。インターセプターによる認証管理、TypeScriptとの親和性、自動JSON変換など、実務で求められる機能がバランスよく揃っています。近年はfetch APIの進化により「axiosは不要」という議論もありますが、インターセプターやインスタンス管理といった機能が必要なプロジェクトでは、依然として有力な選択肢です。