はじめに
Nuxt.jsにてクライアントサイドのvueからサーバのREST APIを呼び出す際に、vue内のスクリプトにロジックを書くと、他の場所で流用できない。そのため、外部のjsに共通ロジックとしてサーバのAPIを呼び出す処理を記述したかったが、あまり良い例が無かったので、検討&実装してみた(正しいかは不明)
Vuexストア内でaxiosを使ってサーバAPIを呼び出すみたなことをやってる人も居たけど、それはちょっと違うだろう(というか気持ち悪い)ということで、pluginsに共通ロジックを作成することにした。
構成
修正する対象は以下の3ファイル(pages/index.vue , plugins/axios.js , plugins/api.js)
ROOT
├─.nuxt
├─assets
├─components
├─layouts
├─middleware
├─pages
│ index.vue
├─plugins
│ api.js
│ axios.js
├─server
├─static
├─store
└─test
axios.js
以下の記事を参考に、pluginsフォルダ配下にaxios.jsを作成する。
今回は記事のまま修正はしていない。このプラグインを作成することで、axiosでサーバアクセスする際、
リクエスト発生時、エラー発生時に処理をフックして任意の処理を実行することができる。
$axios.onResponseでレスポンス時にフックすることも可能。
https://axios.nuxtjs.org/extend
exportdefaultfunction({$axios,redirect}){$axios.onRequest((config)=>{console.log('Making request to '+config.url)})$axios.onError((error)=>{constcode=parseInt(error.response&&error.response.status)if(code===400){redirect('/400')}})}
api.js
このjsがapiを呼び出す共通部品。
exportdefaultfunction({$axios},inject){constapi=newAPI($axios)inject('api',api)}classAPI{constructor(axios){this.axios=axios}asyncgetHoge(){constres=awaitthis.axios.$get('http://localhost:3000')console.log(res)}}
次の処理を入れることで、後述するvue内で $apiとしてアクセスすることができるようになる。
inject('api', api)
ここまで作成したら、 nuxt.config.js 内の plugins に次のように記載する。
plugins:['~/plugins/axios','~/plugins/api'],
idnex.vue
index.vueの<script>部分だけを抜粋。
asyncData() 内ではthisが使えないので、context.app.\$api.getHoge()
mounted() 内などのthisが使える箇所では、this.\$api.getHoge()
とすることで、api.jsに記載したaxiosの共通ロジックを呼び出すことができる。
<script>importLogofrom'~/components/Logo.vue'exportdefault{components:{Logo},asyncData(context){context.app.$api.getHoge()return{}},mounted(){this.$api.getHoge()}}</script>
まとめ
この記述がNuxt.jsとして正しいかどうかは、少し微妙なところ。
そもそもAPIクラスを作成する必要が無く、inject('メソッド名', function)とすればよい。
しかし、今回作成したかったアプリケーションは、バックエンドが複数あり、
そのバックエンド毎に処理を実行する共通インスタンス(この例では\$api)を
作成したかったからこのようにしている。
\$backendA.getHoge(), \$backendB.getHoge()のような感じ。
参考
- Axios Module
https://axios.nuxtjs.org/
なぜNuxt.jsの本家サイトにこの例が記載されていないのかが謎ってくらい「なるほどね」ってなった。 - Nuxt.jsでaxiosの共通処理を作成し、API呼び出し処理をラップして使用する
https://qiita.com/itouuuuuuuuu/items/4132e3b7ddf2cbf02442
最初この記事を見つけたときは「おぉ!!」ってなった。次の2点を自分なりに改善してみたのが本記事。- export let axios;
plugins/axios/index.js 内で export let axios; としている。
axiosをexportしたかったからこのようにしたんだと思うけども、
これだとESLintのimport/no-mutable-exports に引っかかってしまう。 - import UserApi from '@/plugins/axios/modules/user'
作成した共通部品をvue内で使用する際にimportしなければならない。
これは地味にメンドイ。
- export let axios;