2010年代も終わるのでaxiosについて確認しておきたい


この記事は[JavaScript 2 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/javascript2) 20日目 の記事です。

Jserのみなさまこんにちは。
JavaScriptが大好きな[りゅーそう](https://twitter.com/ryusou_mtkh)と申します。

私はJavaScriptが好きですが、現状雰囲気で書いてしまっているといった感じの残念な人です。
~~今回紹介するaxiosも正直、雰囲気で使っています。~~

このままaxiosを雰囲気で使ってしまっていていいのか？このまま年を越していいのか？と危機感を覚え、貴重なJavaScriptのAdvent Calenderの１枠をいただきまして、axiosの使い方をアウトプットさせてください。

axiosをテーマに書かれた記事なんてもうすりおろされまくってるだろ！というみなさま。大変申し訳ありません。そういった方はぜひ、この記事を読んで、「そんなこと余裕で理解してるわ！」と気持ちよく年を越してください。
axiosを雰囲気で使っている皆さま、この記事を読んで、安心して年を越しましょう。

ですので、初心者向けの内容になるかと思います。

よく調べた上で、記述しておりますが、もし説明に誤りや不備があった場合はご指摘いただけるとありがたいです。（何しろ上のリンクのような経歴なので）

#書くこと
・axiosとはなんなのか
・なぜaxiosを使うのか
・axiosの使い方


#axiosとは

公式を読めばわかるようなことを書きます。
https://github.com/axios/axios#axiosgeturiconfig

これによるとaxiosとは


>Promise based HTTP client for the browser and node.js

とあります。
**ブラウザおよびnode.js用のPromiseベースのHTTPクライアント**(Google翻訳）
......これはどういうことでしょうか？

HTTP通信を行うためにもっとも多く使われているAPIは[XMLHttpRequest](https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest)で、このAPIはユーザーエージェント（ブラウザ、画面を表示している部分）とサーバーとの間でのHTTP通信を行うことができます。
現在では、[Fetch API](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API)を使うのが一般的だと思われます。

ただ、これらのAPIはブラウザ側でしか使うことができず、Node（サーバー）上で通信を行うことができません。Node上でHttp通信行う際に[request](https://github.com/request/request)などを用いてサーバーを立てたり、http通信を行うケースもあると思います。

つまり、axiosがブラウザおよび、node.js用のHTTPクライアントということはブラウザ上でも、node.js上でも使用できるHTTPクライアントだということです。

このようにaxiosは**ユニバーサルHTTPクライアント**な性質を持っています。
ブラウザ側のHTTP通信はXMLHttpRequestの形をとっているので、[XSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery)に対応します。
[Promise API](https://azu.github.io/promises-book/)ベースのHttpクライアントです。

#なぜaxiosか
前節でほぼ書いてしまった感がありますが、JavaScriptが流行している中で、サーバーサイドをNode.jsで実装したり、BFFといった構成を取ること、Next.jsなどのフレームワークを用いてSSRを行うケースもあると思います。
そういった中で、ユニバーサルHttpクライアントであるaxiosを採用するという選択もあるのではないでしょうか。
~~私は、なんとなく書きやすいというだけの理由で使っています。~~

※FetchAPIや他のHttp Clientとのパフォーマンスの比較などは詳しくないので、詳しい方ぜひコメントください。

#使い方
正直、Read.meみてくださいな話も多いと思いますが、説明のために引用します。
(https://github.com/axios/axios)

##ブラウザ側の実装

###インストール

```terminal
npm install axios
```


###GETメソッド

Promiseベースなので、このようにPromiseで書くことでエラーバンドリングをすることができます。

```javascript
import axios from 'axios';

axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
  .finally(function () {
 
  });
```
もちろん、async/awaitで書くこともできます。
try/catchでエラーハンドリングを行います。

```javascript
async function getUser() {
  try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}
```

###POSTメソッド
）略
GETメソッド同様にPromiseを使って書くことができます。

###Node.jsで実装

こちらの記事がとても参考になると思います。

[axios、async/awaitを使ったHTTPリクエスト(Web APIを実行)](https://qiita.com/shisama/items/61cdcc09dc69fd8d3127)


###axios.create

前章でのaxiosでの処理はこのようにURLなど様々な設定することができます。

```javascript
axios({
  method: 'get',
  url: '/user/12345',
});
```

ただ、このような同じ設定をしたかったり、データをhtmlで受け取ったり、JSON形式で受け取ったり様々な設定をしたい場合があると思います。
そんな時は
**axios.create()**  を使います。

例えば、basedURLをlocalで実行し、JSON形式でGET処理をしたい場合、

```javascript:axios.js
import axios from `axios`

 export const Instance = axios.create({ 
   baseURL: `http:localhost:8000`, 
 //htmlが欲しければtext, imageが欲しければ、streamなどを呼び出す。
   headers: { 'Content-Type': 'application/json' }, 
   responseType: 'json'
 }) 
```

このようにモジュールを作成し、それを呼び出して実行します。

```javascript:index.js
import Instance from './axios.js'

Instance.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
});
```

このように、axios.create（）を用いることで、様々な設定を行うことができます。詳しくはRead.meをご覧ください。




##TypeScriptでaxios

TypeScriptの利用率が60%に迫っています。すごい。。。。TypeScriptで使いたいという方も多いのではないでしょうか？

ソース： [The State of JavaScript 2019](https://2019.stateofjs.com/javascript-flavors/)

##インストール
ts.cpnfig.jsonを作成

```terminal
tsc --init
```


型定義ファイルもインストールします。

```terminal
npm i axios
npm i -D @types/axios
```

型定義ファイルをみてみましょう。(該当箇所だけ一部抜粋）

```javascript:node_modules/axios/index.d.ts
export interface AxiosRequestConfig {
  url?: string;
  method?: Method;
  baseURL?: string;
  transformRequest?: AxiosTransformer | AxiosTransformer[];
  transformResponse?: AxiosTransformer | AxiosTransformer[];
  headers?: any;
  params?: any;
  paramsSerializer?: (params: any) => string;
  data?: any;
  timeout?: number;
  withCredentials?: boolean;
  adapter?: AxiosAdapter;
  auth?: AxiosBasicCredentials;
  responseType?: ResponseType;
  xsrfCookieName?: string;
  xsrfHeaderName?: string;
  onUploadProgress?: (progressEvent: any) => void;
  onDownloadProgress?: (progressEvent: any) => void;
  maxContentLength?: number;
  validateStatus?: (status: number) => boolean;
  maxRedirects?: number;
  socketPath?: string | null;
  httpAgent?: any;
  httpsAgent?: any;
  proxy?: AxiosProxyConfig | false;
  cancelToken?: CancelToken;
}

export interface AxiosResponse<T = any>  {
  data: T;
  status: number;
  statusText: string;
  headers: any;
  config: AxiosRequestConfig;
  request?: any;
}

export interface AxiosError<T = any> extends Error {
  config: AxiosRequestConfig;
  code?: string;
  request?: any;
  response?: AxiosResponse<T>;
  isAxiosError: boolean;
}
```

先ほどの例だと、AxiosRequestConfigに型定義がされているので、そのまま使えるということになります！

```javascript:api.ts

import axios from `axios`

 export const Instance = axios.create({ 
   baseURL: `http:localhost:8000`, 
   headers: { 'Content-Type': 'application/json' }, 
   responseType: 'json'
 }) 
```
```javascript:index.ts
import { Instance } from './api';

Instance('/user?ID=12345')
  .then(function(res) {
    console.log(res);
  })
  .catch(function(err) {
    console.log(err);
  });
```
ターミナルで以下のコマンドを実行します。


```terminal
tsc
```

以下のようなファイルが出力されました。

```javascript:index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var api_1 = require("./api");
api_1.Instance('/user?ID=12345')
    .then(function (res) {
    console.log(res);
})
    .catch(function (err) {
    console.log(err);
});
```

だからなに？って感じかも知れませんが。。。。。（笑）
axiosの型定義を拡張してGET,POSTメソッドに型推論を効かせたりすることもできます。
axiosの型拡張については[実践TypeScript](https://www.amazon.co.jp/dp/B07T477V6G/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)に詳しいので、興味のある方はぜひ読んでみてください！（とても参考になります！~~その本の内容のコピペになりそうなので、ここでは割愛します。モヤモヤさせてしまった。。。すいません~~）

#まとめ
axiosはブラウザ、node.jsに対応した便利なHTTPクライアント
簡潔にHTTP通信の処理が書けるし、あらゆるデータに対応できる。

TypeScriptをしていて、axiosを使われている方は[実践TypeScript](https://www.amazon.co.jp/dp/B07T477V6G/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)を読んでスッキリ年越ししましょう。（すいません）





最後まで読んでいただき、ありがとうございました！
それでは、良いお年を！