はじめに
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でレスポンス時にフックすることも可能。
export default function ({ $axios, redirect }) {
$axios.onRequest((config) => {
console.log('Making request to ' + config.url)
})
$axios.onError((error) => {
const code = parseInt(error.response && error.response.status)
if (code === 400) {
redirect('/400')
}
})
}
api.js
このjsがapiを呼び出す共通部品。
export default function ({ $axios }, inject) {
const api = new API($axios)
inject('api', api)
}
class API {
constructor (axios) {
this.axios = axios
}
async getHoge () {
const res = await this.axios.$get('http://localhost:3000')
console.log(res)
}
}
次の処理を入れることで、後述するvue内で $api としてアクセスすることができるようになる。
inject('api', api)
ここまで作成したら、 nuxt.config.js 内の plugins に次のように記載する。
plugins: [
'~/plugins/axios',
'~/plugins/api'
],
index.vue
index.vueの<script>部分だけを抜粋。
asyncData() 内ではthisが使えないので、context.app.$api.getHoge()
mounted() 内などのthisが使える箇所では、this.$api.getHoge()
とすることで、api.jsに記載したaxiosの共通ロジックを呼び出すことができる。
<script>
import Logo from '~/components/Logo.vue'
export default {
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;