Nuxt.jsでaxiosモジュールを使って通信を行う場合、リクエストへ認証情報追加やエラーハンドリングなどの共通処理をaxiosプラグインに定義できる。
Vueコンポーネントなどでaxiosによる通信を行う場合はこれらの共通処理を利用することができるが、自作のAPIクラスでは利用できない問題を、APIを登録する自作プラグインの登録により解決する方法について記述する。
axiosを利用するAPIクラスを実装し、これをインポートして通信を行う。
axiosプラグイン。
export default function ({$axios, redirect}) {
$axios.onRequest(config => {
// ここで認証情報付加などが行える
console.log('Making request to ' + config.url)
})
$axios.onError(error => {
if (!error.response) {
return
}
const code = error.response.status
if (code === 401) {
redirect('/login')
}
// ....
})
}
APIクラス。
import axios from 'axios'
class UserApi {
constructor() {
this.url = '/api/users'
}
list() {
return axios.get(this.url)
.then(data => data.data)
.catch(err => {throw err})
}
}
const userApi = new UserApi()
export default userApi
axiosプラグインを登録。
module.exports = {
// ....
plugins: [
'~/plugins/axios',
],
modules: [
'@nuxtjs/axios',
],
// ....
}
<script>
import userApi from '~/api/user'
export default {
async asyncData ({ app }) {
// const items = await app.$axios.$get('/api/users') // APIクラスを利用しない場合
const items = await userApi.list()
return {
users: items.users
}
},
data() {
return {
users: [],
}
},
methods: {
async reload() {
// const items = await this.$axios.$get('/api/users') // APIクラスを利用しない場合
const items = await userApi.list()
this.users = items.users
},
}
}
</script>
APIのリストを保持するクラスとAPIを登録するプラグインを新設することにより共通処理を利用可能とする。これによりAPIの呼び出し方法は$axios
と同様になる。
変更無し。
プラグインの格納位置を変更すると共にクラスから関数形式に変更。
export default axios => ({
list() {
return axios.get('/api/users')
.then(data => data.data)
.catch(err => {throw err})
},
})
APIリストを保持するJavaScriptファイルを新設。
class ApiDefinition {
constructor(name, func) {
this.name = name
this.func = func
}
}
const apiDefs = []
export default apiDefs
import userApi from './apis/user'
apiDefs.push( new ApiDefinition('userApi', userApi) )
APIを登録するプラグインを新設。
import apiDefs from '~/api/define'
export default ({ $axios }, inject) => {
apiDefs.forEach((apiDef) => {
console.log(`regist API: ${ apiDef.name }`)
inject(apiDef.name, apiDef.func($axios))
})
}
apiregister
プラグインを追加登録。
module.exports = {
// ....
plugins: [
'~/plugins/axios',
'~/plugins/apiregister',
],
modules: [
'@nuxtjs/axios',
],
// ....
}
APIのインポートを削除して$axios
と同様の利用方法に変更する。
<script>
export default {
async asyncData ({ app }) {
// const items = await app.$axios.$get('/api/users') // APIクラスを利用しない場合
const items = await app.$userApi.list()
return {
users: items.users
}
},
data() {
return {
users: [],
}
},
methods: {
async reload() {
// const items = await this.$axios.$get('/api/users') // APIクラスを利用しない場合
const items = await this.$userApi.list()
this.users = items.users
},
}
}
</script>
API登録のせいか微妙に初期表示が遅くなる?