38
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【JavaScript】axiosがfetchより使いやすいと思う理由

Last updated at Posted at 2022-09-11

JavaScriptでAPIを叩く際に使用する代表的な武器として、fetchとaxiosが挙がると思います。

fetchはJavaScriptの標準ライブラリなのに対し、axiosはインストールする必要があります。

それでも僕がaxiosがfetchより使いやすいという理由を、ざっくりと両者の特徴を紹介しながらいくつか述べてみました!

サンプルのAPIとして、猫の雑学(英語)をランダムで返してくれるcatfact.ninjaをお借りしています😺

https://catfact.ninja/fact

1. エラーハンドリング

【fetchの場合】

fetchは、サーバのレスポンスが届きはじめた時点でPromiseを解決するという特徴があります。つまり、サーバのレスポンスが届きさえすれば、とりあえずPromiseのresolve()が実行されてしまうということです。

これが、若干不便です。
400エラーや500エラーが起きた場合でも、thenの中が実行されてしまうのです。

たとえば、以下のようなプログラムがあったとします。

fetch('https://catfact.ninja/foo').then((response) => {
  console.log(response);
  alert('Success!');
}).catch((error) => {
  console.error(error);
});

https://catfact.ninja/fooというURLは存在しないので、404ステータスが返るのですが、このプログラムを実行すると、ブラウザに「Success!」というアラートが出ます。

ステータスがどうであれ、サーバー(catfact.ninja)にリクエストが飛んでレスポンスを返しているのでPromiseはresolveを実行し、thenの中の処理が実行されたという訳です。

以下が404ステータスが返った場合のResponseオブジェクトの内容になります。

{
  body: ReadableStream,
  bodyUsed: false,
  headers: Headers,
  ok: false,
  redirected: false,
  status: 404,
  statusText: "",
  type: "cors",
  url: "https://catfact.ninja/foo"
}

fetchが返すResponseオブジェクトには、okというプロパティがあります。(上記4つ目のプロパティ)

レスポンスのステータスが200~299の場合、okプロパティがtrueになり、それ以外のステータスの場合はfalseになります。

このokプロパティを利用してthenの中に分岐を入れてあげることで、200~299以外のステータスの場合のハンドリングが可能になります。

とはいえ、エラーが発生しているのにthenの中が実行されることに、僕は少しだけ違和感を感じちゃいます...

fetch('https://catfact.ninja/foo').then((response) => {
  if (response.ok) {
    console.log(response);
    alert('Success!');
  } else {
    alert('Error!');
  }
}).catch((error) => {
  console.error(error);
});

ちなみに、200~299以外でもthenが実行されるのなら、catchはどのような場合に実行されるのかと、疑問に思う方もいると思います。
fetchにおいて、catchはレスポンスがない場合、つまり通信状況の不具合などでHTTP通信そのものが失敗した場合に実行されます。

【axiosの場合】

axiosでは、200~299以外のHTTPステータスがレスポンスで返ってきた場合にはcatchが実行されます。
なので、以下のプログラムを実行すると、サーバーから404レスポンスが返り、catchが実行されブラウザにError!というアラートが表示されます。

axios.get('https://catfact.ninja/foo').then((response) => {
  alert('Success!');
}).catch((error) => {
  alert('Error!');
});

2. GETメソッド以外の通信

【fetchの場合】

fetchを使用する場合、GET以外のメソッドのHTTP通信を行う場合には、以下のように実行時の第二引数のプロパティmethodでHTTPメソッドを指定することでPOST通信などが可能になります。

また、リクエストボディを設定する際は、第二引数のプロパティにbodyJSON.stringifyでJSON形式にフォーマットしたオブジェクトを設定します。

fetch('api/v1/users', {
  method: 'POST',
  body: JSON.stringify({
    name: 'Whopper',
    age: 24
  })
}).then((response) => {
  alert('Success!');
}).catch((error) => {
  alert('Error!');
});

【axiosの場合】

axiosの場合は、それぞれのHTTPメソッド毎にメソッドが用意されてます。

また、リクエストボディを設定する際は、第二引数に渡したいオブジェクトを設定します。
デフォルトでJSON形式にフォーマットされる為、JSON.stringifyの記述は不要になります。

axios.post('api/v1/users', {
  name: 'Whopper',
  age: 24
}).then((response) => {
  alert('Success!');
}).catch((error) => {
  alert('Error!');
});

3. JSONの取得

【fetchの場合】

fetchでは、レスポンスにJSONデータを含む場合、基本的にthenが2つあったりします。

1つめのthenの中で実行されているresponse.json()というやつが、レスポンスのJSONを解析しているメソッドになります。

その返り値を、2つめのthenの引数として渡されているような感じです。

fetch('https://catfact.ninja/fact').then((response) => {
  return response.json();
}).then((responseJson) => {
  console.log(responseJson);
});

【axiosの場合】

axiosでは、レスポンスオブジェクトのdataへアクセスすることで、JSON解析済みのオブジェクトを参照することができます。

JSON解析のためにthenを増やす必要がないので、見た目もすっきりします。

axios('https://catfact.ninja/fact').then((response) => {
  console.log(response.data);
});

4. インターセプター

【fetchの場合】

fetchでは、標準機能を用いてインターセプターを実装することができません。

fetch-interceptというライブラリを使用したり、fetchメソッド自体をオーバーライドしたりする必要があります。

【axiosの場合】

axiosでは、標準機能でインターセプターを実装することができます。

以下では、リクエストを送信する際にリクエスト送信というログを出すリクエストインターセプターを定義しています。

axios.interceptors.request.use((config) => {
  console.log('リクエスト送信');
  return config;
});

以下では、レスポンスを受信した際にレスポンス受信というログを出すレスポンスインターセプターを定義しています。

axios.interceptors.response.use((response) => {
  console.log('レスポンス受信');
  return response;
});

5. リクエスト時の共通設定を定義

axiosではcreateメソッドを利用することでaxiosのインスタンスが作成できます。
これを利用することで、リクエスト毎のタイムアウトの時間や、ベースURLや、共通のヘッダーなどを定義することができます。

const baseRequest = axios.create({
  baseUrl: 'https://catfact.ninja',
  timeout: 2000
});

baseRequest.get('/fact').then((response) => {
  console.log(response.data);
}).catch((error) => {
  console.error(error);
});

まとめ

まとめると、axiosは以下の点でfetchより使いやすいと考えています。

  1. 200~299以外のステータスの場合はcatchが実行される
  2. HTTPメソッド毎にメソッドが用意されているのでGET以外の通信が楽
  3. レスポンスオブジェクトのdataプロパティで、解析済みのJSONデータを取得できる
  4. インターセプターの実装が楽
  5. 通信時の共通設定の定義が楽

他にも、「axiosはこういう点も便利!」や「fetchはこういう点で素晴らしい!」などがありましたら、是非コメントをお願いします!
最後まで読んでいただき、ありがとうございました!

38
27
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?