axios、async/awaitを使ったHTTPリクエスト(Web APIを実行)

axiosというHTTPリクエストを行うためのライブラリがあります。
Node.js 7からasync/awaitを使えるようになりました。
今回はaxiosとasync/awaitを組み合わせて可読性の高い非同期通信を行う方法について紹介します。
今回のサンプルコードはNode.js 7以降で動作確認済です。

# axios
- [GitHubリポジトリ](https://github.com/axios/axios)
- 発音はアクシオスのようです。 http://ejje.weblio.jp/content/Axios
- 戻り値がPromiseベースなのでjQueryの$.ajaxやFetch APIのように使える
- ブラウザだけでなくNode.jsでも使える

## 使い方

npmからaxiosをインストールします。

```bash
npm install axios --save
```

APIはQiitaさんのAPIを使わせていただきました。


```js
const axios = require('axios');
const url = "https://qiita.com/api/v2/items";

axios.get(url).then(res => {
  const items = res.data;
  for (const item of items) {
    console.log(`${item.user.id}: \t${item.title}`);
  }
}).catch(error => {
  const {
    status,
    statusText
  } = error.response;
  console.log(`Error! HTTP Status: ${status} ${statusText}`);
});
```

上記の通り、axiosでWeb API叩いたらPromiseオブジェクトが返ってくるので、
それを`then`でつないで処理します。
存在しないURLに対してリクエストしていた場合などはErrorが発生するので`catch`する必要があります。

2019/01/24の時点での実行結果は以下の通り

```
hp_kj: 	postgres 公式サイト データベースサンプル dvdrental
jhfgjfgjhghj: 	JP~!!日本 ベトナム ライブ
d_uchida: 	pokemon_data.jsonの中身を見てみる
jpkhantvcust78: 	{live~Free}}*Vietnam vs Japan Live stream
artistan: 	ライブラリを使わず、JSで画像をフェードインさせてみる
_ayk_study: 	【Rails API】ActionController::InvalidAuthenticityTokenの解決方法
kotaro-dr: 	【Flask】Blueprintで分割したControllerを跨いでのurl_for()
Ping: 	PlantUML Server で爆速プレビュー！ for Mac
AykeJq0ILeYFOR4: 	今日の勉強記録１　bashについて
miler0528: 	get_object_or_404 がなぜ404ページを送信できるのか、調べてみた(Django)
mkyz08: 	Apache Camelでサーキットブレーカーパターン（Circuit Breaker Pattern）その2（Hystrix Dashboardを試す）
meznat: 	[python]dotenvで環境変数をローカルから読み込む
atsushi586: 	今日から開発で使えるサクラエディタ機能
Q11Q: 	Ms Accessの起動スイッチと天才的としかいいようのない裏技
nouka: 	ガード節を使って読みやすいコードを書こう
33yuki: 	【PHP】変数の内容を出力する関数いろいろ
sawadashota: 	[Laravel] エンドポイントが自動で変わるHeroku Redisに適応する
Q11Q: 	条件付きコンパイル 環境対応編纂命令 Const Directive And Conditional Compilation
binary2: 	vueでmomentを使うときにはまったこと..
tmitani: 	さまざま分布のQQプロットを描画してみる

```
しかし、`Promise`は直列で実行したい関数が増えればネストが深くなりがちです。

```js
f1(param) {
  f2(param).then((data1) => {
    f3(data1).then((data2) => {
      f4(data2).then((data3) => {
        ・・・
      });
    });
  });
}
```

そこでさらに可読性を高くするためにasync/awaitを用いてみます。

# async/await
というわけで今回の記事の最終地点です。
さっきのaxiosを使ったサンプルコードをasync/awaitを使って修正してみます

```js
const axios = require('axios');
const url = "https://qiita.com/api/v2/items";

async function main() {
  try {
    const res = await axios.get(url);
    const items = res.data;
    for (const item of items) {
      console.log(`${item.user.id}: \t${item.title}`);
    }
  } catch (error) {
    const {
      status,
      statusText
    } = error.response;
    console.log(`Error! HTTP Status: ${status} ${statusText}`);
  }
}

main();
```
async/awaitを使うには関数の前に`async`を付けます。
そのasync関数内で`Promise`を返す関数を呼び出すところで`await`を付けると結果を取得して後続の処理を行います。

また、async/awaitで書くとtry-catchでエラーをキャッチできます。

これでPromiseチェーンでできるネストの問題も以下のように解決できます。

```js
async f1(param) {
  const data1 = await f2(param);
  const data2 = await f3(data1);
  const data3 = await f4(data2);
  ・・・
}
```

ちなみにasync/awaitはNode v7以降しか使えません。6以前はbabel使ってください。
[Babel 6.7 で async/await する - Qiita](http://qiita.com/hashedhyphen/items/44701fcc18bd40066aa7)

以上になります。
最後までお読み頂きありがとうございました。
質問や不備などがありましたら、[Twitter](https://twitter.com/shisama_)でメンションとばすかコメント欄にてお願いいたします。

今回のサンプルコードは以下においておきます。
https://github.com/shisama/axios_sample