JavaScriptで非同期処理を実装する際によく利用されるFetch APIとaxiosの違いについて紹介します。
目次
前提知識: fetchもaxiosも戻り値はPromise
fetchもaxiosも戻り値はPromiseです。ですので、成功時(fulfilled)の戻り値はthen()あるいはawaitで取得します。
Promiseの詳細解説はJavaScriptの非同期処理で理解必須!Promiseの概要・挙動まとめで紹介しています。
fetchの戻り値のサンプルコード
thenを利用する場合
const logTodoResponse = () => {
fetch("http://localhost:4000/todos/1", {
method: "GET",
}).then((response) => console.log(response));
};
// 実行結果
logTodoResponse();
// Response {
// size: 0,
// [Symbol(Body internals)]: {
// ...
async/awaitを利用する場合
const logTodoResponse = async () => {
const response = await fetch("http://localhost:4000/todos/1", {
method: "GET",
});
console.log(response);
};
// 実行結果
logTodoResponse();
// Response {
// size: 0,
// [Symbol(Body internals)]: {
// ...
axiosの戻り値のサンプルコード
thenを利用する場合
const logTodoResponse = () => {
axios
.get(`http://localhost:4000/todos/1`)
.then((response) => console.log(response));
};
// 実行結果
logTodoResponse();
// {
// status: 200,
// statusText: 'OK',
// headers: {
// ...
// ...
async/awaitを利用する場合
const logTodoResponse = async () => {
const response = await axios.get(`http://localhost:4000/todos/1`);
console.log(response);
};
// 実行結果
logTodoResponse();
// {
// status: 200,
// statusText: 'OK',
// headers: {
// ...
// ...
fetchとaxiosの比較表
fetchとaxiosの違いをまとめた表が以下になります。
| データ取得 | HTTPメソッド指定方法 | ステータスコード取得 | 例外処理(responseなし) | 例外処理(responseあり) | |
|---|---|---|---|---|---|
| fetch | response.json() | methodプロパティで指定 | response.okの真偽値 | response.okで判断 | catchで処理 |
| axios | response.data | aliasで指定可能 | response.status | catchで処理 | catchで処理かつ、レスポンス有無で分岐 |
以下ではそれぞれの観点について説明をします。
データ取得について
戻り値をresponseとした場合、fetchのリクエストレスポンスはresponse.json()で参照できます。axiosの場合はresponse.dataで参照できます。
fetchを利用したデータ取得のサンプルコード
thenを利用する場合
const getTodo = () => {
const todo = fetch("http://localhost:4000/todos/1", {
method: "GET",
}).then((response) => response.json());
return todo; // { id: 1, content: 'go somewhere', completed: true }
};
// 実行結果
// 戻り値はPromiseなので、then()を利用してデータを参照する
getTodo().then((todo) => console.log(todo));
// { id: 1, content: 'go somewhere', completed: true }
async/awaitを利用する場合
const getTodo = async () => {
const response = await fetch("http://localhost:4000/todos/1", {
method: "GET",
});
return response.json(); // { id: 1, content: 'go somewhere', completed: true }
};
// 実行結果
// async関数はPromiseを返すので、then()を利用してデータを参照する
getTodo().then((todo) => console.log(todo));
// { id: 1, content: 'go somewhere', completed: true }
axiosを利用したデータ取得のサンプルコード
thenを利用する場合
const getTodo = () => {
const todo = axios
.get(`http://localhost:4000/todos/1`)
.then((response) => response.data);
return todo; // { id: 1, content: 'go somewhere', completed: true }
};
// 実行結果
getTodo().then((todo) => console.log(todo));
// { id: 1, content: 'go somewhere', completed: true }
async/awaitを利用する場合
const getTodo = async () => {
const response = await axios.get(`http://localhost:4000/todos/1`);
return response.data; // { id: 1, content: 'go somewhere', completed: true }
};
// 実行結果
getTodo().then((todo) => console.log(todo));
// { id: 1, content: 'go somewhere', completed: true }
HTTPメソッドの指定方法について
fetchでHTTPメソッド(getやpostなど)を指定する場合はmethodプロパティを利用します。
axiosの場合もmethodプロパティで指定できますが、axios.getのようなエイリアスが用意されています。
以下ではPOSTメソッドを例にfetchと、axiosのエイリアスメソッドの違いについて紹介します。
fetchを利用した場合のHTTPメソッドの指定方法
const postTodo = async () => {
const postItem = { content: "go shopping", complated: false };
const response = await fetch("http://localhost:4000/todos", {
method: "POST",
body: JSON.stringify(postItem),
headers: {
"Content-Type": "application/json",
},
});
return response.json();
};
// 実行結果
postTodo().then((todo) => console.log(todo));
// { content: 'go shopping', complated: false, id: 3 }
axiosのエイリアスによるHTTPメソッドの指定方法
const postTodo = async () => {
const postItem = { content: "go", complated: false };
const response = await axios.post(
`http://localhost:4000/todos`,
postItem
);
return response.data;
};
// 実行結果
postTodo().then((todo) => console.log(todo));
// { content: 'go shopping', complated: false, id: 3 }
HTTPレスポンスステータスコードについて
fetchの場合はHTTPレスポンスステータスコードが200系の場合、response.okはtrueになります。ですので、fetchでは『200系 or 200系以外』という判別方法になります。
一方、axiosの場合はresponse.statusに具体的なHTTPレスポンスステータスコードが記述されています。
レスポンスありのエラーハンドリングについて
『レスポンスありのエラーハンドリング』とは404や500などの200系以外のHTTPレスポンスステータスコードが返された時の処理についてです。
fetchの場合、ステータスコードにかかsわらずレスポンスが返された場合はfulfilledなPromiseオブジェクトが返されます。
ですので、レスポンスありのエラーハンドリングはresponse.okがfalseの条件下に記述します。
一方axiosの場合、200系以外のレスポンスが返された場合はデフォルトでrejectedなPromiseオブジェクトを返すため1、catchあるいはthenの第2引数で処理をします。
fetchを利用したエラーハンドリング例(レスポンスあり)
thenを利用する場合
const getTodo = () => {
// 存在しないリソースを参照する(404エラー発生)
const todo = fetch("http://localhost:4000/todos/4", {
method: "GET",
}).then((response) => {
if (response.ok) {
console.log(response);
return response.json();
} else {
// レスポンスありのエラーハンドリング(実際には必要に応じた例外処理を実装する)
console.log("response is not ok");
return {};
}
});
return todo;
};
// 実行結果
getTodo().then((todo) => console.log(todo));
// response is not ok
// { }
async/awaitを利用する場合
const getTodo = async () => {
// 存在しないリソースを参照する(404エラー発生)
const response = await fetch("http://localhost:4000/todos/4", {
method: "GET",
});
if (response.ok) {
return response.json();
} else {
// レスポンスありのエラーハンドリング(実際には必要に応じた例外処理を実装する)
console.log("response is not ok");
return {};
}
};
// 実行結果
getTodo().then((todo) => console.log(todo));
// response is not ok
// { }
axiosを利用したエラーハンドリング例(レスポンスあり)
thenを利用する場合
const getTodo = () => {
const todo = axios
.get(`http://localhost:4000/todos/4`) // 存在しないリソースを参照する(404エラー発生)
.then((response) => response.data)
.catch((error) => {
// レスポンスありのエラーハンドリング(実際には必要に応じた例外処理を実装する)
console.log(
`Error! code: ${error.response.status}, message: ${error.message}`
);
return error.response.data;
});
return todo;
};
// 実行結果
getTodo().then((todo) => console.log(todo));
// Error! code: 404, message: Request failed with status code 404
// {}
async/awaitを利用する場合
const getTodo = async () => {
const response = await axios
.get(`http://localhost:4000/todos/4`) // 存在しないリソースを参照する(404エラー発生)
.catch((error) => {
// レスポンスありのエラーハンドリング(実際には必要に応じた例外処理を実装する)
console.log(
`Error! code: ${error.response.status}, message: ${error.message}`
);
return error.response;
});
return response.data;
};
// 実行結果
getTodo().then((todo) => console.log(todo));
// Error! code: 404, message: Request failed with status code 404
// {}
レスポンスなしのエラーハンドリングについて
『レスポンスなしのエラーハンドリング』とはネットワークエラー等でAPIの通信自体が失敗した時の処理についてです。
レスポンスがない場合はfetchもaxiosもrejectedなPromiseオブジェクトを返します。
fetchの場合、レスポンスが返ってくるとfulfilledなPromiseオブジェクトを返すため、catchあるいはthenの第2引数で処理する内容がレスポンスなしのエラーハンドリングになります。
一方、axiosの場合は200系以外のレスポンスが返ってくるとデフォルトでrejectedなPromiseオブジェクトを返すため、responseの有無でさらに条件分岐をさせる必要があります。
fetchを利用したエラーハンドリング例(レスポンスなし)
const getTodo = async () => {
// レスポンスが返ってこないエラーを再現するため、不正なポートを利用
const response = await fetch(`http://localhost:1234/todos/1`, {
method: "GET",
}).catch((error) => {
// レスポンスなしのエラーハンドリング(実際には必要に応じた例外処理を実装する)
throw new Error(`No response! ${error.message}`);
});
if (response.ok) {
return response.json();
} else {
// レスポンスありのエラーハンドリング(実際には必要に応じた例外処理を実装する)
return {};
}
};
// 実行結果
getTodo()
.then((todo) => console.log(todo))
.catch((error) => console.log(error));
// Error: No response! request to http://localhost:1234/todos/1 failed, reason: connect ECONNREFUSED 127.0.0.1:1234
// at ...
// at ...
// at ...
axiosを利用したエラーハンドリング例(レスポンスなし)
const getTodo = async () => {
const response = await axios
.get(`http://localhost:1234/todos/1`) // レスポンスが返ってこないエラーを再現するため、不正なポートを利用
.catch((error) => {
if (error.response) {
// レスポンスありのエラーハンドリング(実際には必要に応じた例外処理を実装する)
console.log(
`Error! code: ${error.response.status}, message: ${error.message}`
);
return error.response;
} else {
// レスポンスなしのエラーハンドリング(実際には必要に応じた例外処理を実装する)
throw new Error(`No response! ${error.message}`);
}
});
return response.data;
};
// 実行結果
getTodo()
.then((todo) => console.log(todo))
.catch((error) => console.log(error));
// Error: No response! connect ECONNREFUSED 127.0.0.1:1234
// at ...
// at ...
// at ...
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!
参考資料
- validateStatusオプションを利用すれば挙動を変更できます ↩



