【django/vue.js初学者向け】DjangoRestFrameworkで作成したAPIをVue.jsから叩いてみる

# 目的
django_restframeworkでAPIを作成してみたが、Vue.jsでフロント画面も作成し、フロントからaxiosを利用してAPIを叩くところまでしてみたいと思った
# 実施環境
### ハードウェア環境
| 項目 | 情報 |
|:-:|:-:|
| OS  |macOS Catalina(10.15.7)   |
|ハードウェア   |  MacBook Air (11-inch, Early 2015) |
|プロセッサ   | 1.6 GHz デュアルコアIntel Core i5|
|メモリ   |  4 GB 1600 MHz DDR3 |
|グラフィックス   |  intel HD Graphics 6000 1536 MB |
### ソフトウェア環境
| 項目 | 情報 |
|:-:|:-:|
| homebrew  | 3.3.8 |
| mysql | Ver 8.0.27 for macos10.15 on x86_64 |
| python  | 3.8.12 |
| node | 17.2.0 |
| npm | 8.1.4 |
| @vue/cli | 4.5.15 |
| vue | 2.6.14  |



# 前提
vueとdjango_restframeworkを使ったことがあるが、どのようにしてvueからdjango_restframworkのAPIを叩けばいいかわからない人。

npmとnode.jsがインストールされていること。

確認方法は

```terminal
$ npm -v
$ node -v
```
| 項目 | バージョン |
|:-:|:-:|
| 　　node　　 | 　17.2.0 　|
|　　 npm　　 | 　8.1.4 　|

# 環境構築
#### vueCLIをインストール
VueCLIとはvue.jsで開発の準備を支援してくれるツール

VueCLIがあると

- プロジェクトのテンプレートの作成
- 複数のjsファイルを一つにまとめる
- .vueファイルを.jsに変換する
- トランスパイル
- JavaScriptの構文チェック
- テストツールの導入など

これら全てを行ってくれる。非常に優秀。

インストールする。

```terminal
$ sudo npm i -g @vue/cli
```
```Vue CLI v4.5.15```のインストールが完了

### VueCLIを使ってvueプロジェクトを作る

```
$ vue create プロジェクト名
```
この後に対話式でいくつかの質問に答えるとプロジェクトが作成される
[こちら](https://qiita.com/shizen-shin/items/8b99df87f43c5e21eea4#:~:text=%E4%BD%9C%E6%88%90%E3%81%95%E3%82%8C%E3%82%8B%E3%80%82-,Vue%20CLI%E5%AF%BE%E8%A9%B1%E3%83%A2%E3%83%BC%E3%83%89,-vue%20create%E3%81%A7)参考にしていく。

#### webpack-bundle-trackerをインストール

```npm i webpack-bundle-tracker@0.4.3```

#### 画面確認画面確認
```npm run serve```

### axiosインストール
```npm install --save axios vue-axios```

>　axiosはPromiseベースのHTTP ClientライブラリでGETやPOSTのHTTPリクエストを使ってサーバからデータの取得、データへのデータ送信を行うことができます。

[vue.jsを使ってaxiosを学ぶ](https://reffect.co.jp/vue/vue-axios-learn)より

# vueプロジェクトにAPIを叩く処理を実装



### main.jsでaxiosをimportする

```main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import axios from 'axios' //追記
import VueAxios from 'vue-axios' //追記

Vue.config.productionTip = false

Vue.use(VueAxios, axios) //追記

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')
```
### index.jsでルーティングを実装する
ここではルーティングを実装し、どのURLでどのコンポーネントを表示するかを定義する。

```index.js
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";
import GetMembers from '@/components/GetMembers'

Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "Home",
    component: Home,
  },
   // 追記
   // http://localhost:8080/get_membersでGetMembersコンポーネントが呼ばれる
  {
    path: "/get_members",
    name: "GetMembers",
    component: GetMembers
  },
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes,
});

export default router;
```

### 実際に表示される画面を実装
上記のindex.jsでルーティングされたgetMember.vueでaxiosでdjango_restframeworkのAPIを叩く処理を実装していく。

下記のaxiosの処理によってページが更新される時にhttp://127.0.0.1:8000/api/v1/member/のURLに対してGETメソッドでHTTP通信を行う。

そのレスポンスをMembersプロパティに格納し、ループで各memberのusernameを表示することができる。

```getMember.vue
<template>
  <div>
    <div v-for="(member, key) in Members" :key="key">
      <hr>
      <p>{{ member.username }}</p>
      <hr>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      Members: []
    };
  },
  // ページを読み込んでマウントを行っている状態
  mounted() {
    this.axios
      // APIのURL
      .get("http://127.0.0.1:8000/api/v1/member/")
      // レスポンスをdata()内のMembersプロパティに格納
      .then(response => (this.Members = response.data));
  }
};
</script>
```


実はこれだけでAPIを叩くことはできない。
サーバサイド側でCORSの設定をすることでようやくAPIを叩くことを許可される。

**CORSとは、同一生成元でないところへの要求を安全に許可する仕組みのこと**だが、詳しくは[この神記事](https://qiita.com/att55/items/2154a8aad8bf1409db2b)を確認してほしい

# drfでjwt認証APIの作成方法
と言うことで、djangorestframework側でCORSの設定を行う。

```pip install django-cors-headers```でcorsheadersをインストール

そしてsettings.pyに下記のように記述する

```settings.py
INSTALLED_APPS = [
    # CORS対策用のlib
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware', 
]

# VueからのXMLHttpRequestのアクセスがDRF側でブロックされないようにCORS設定をする
CORS_ALLOWED_ORIGINS = [
    'http://localhost:8080',
]
```
CORS_ALLOWED_ORIGINSにはこのdjangorestframeworkのAPIを叩くことを許可するurlを記載する。

これでとりあえずはフロント(vue)からAPIを叩くことができた。


![スクリーンショット 2021-12-30 午前10.41.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/b78ba0f2-d112-faeb-1a24-e99a4980f7d8.png)
認証周りなどは次回また詳細に記述していく。

# 参考文献
https://qiita.com/taki_21/items/d2905e093d326f72a286
https://stackoverflow.com/questions/35760943/how-can-i-enable-cors-on-django-rest-framework