Skip to content

Instantly share code, notes, and snippets.

@orimajp
Created May 19, 2019 14:36
Show Gist options
  • Save orimajp/9e8c0800922c62b5f4ad57a1811f980c to your computer and use it in GitHub Desktop.
Save orimajp/9e8c0800922c62b5f4ad57a1811f980c to your computer and use it in GitHub Desktop.
Nuxt.jsでaxios-moduleを利用する際に自作APIクラスのリクエスト実行をaxiosプラグイン配下に置く方法

Nuxt.jsでaxios-moduleを利用する際に自作APIクラスのリクエスト実行をaxiosプラグイン配下に置く方法

概要

Nuxt.jsでaxiosモジュールを使って通信を行う場合、リクエストへ認証情報追加やエラーハンドリングなどの共通処理をaxiosプラグインに定義できる。

Vueコンポーネントなどでaxiosによる通信を行う場合はこれらの共通処理を利用することができるが、自作のAPIクラスでは利用できない問題を、APIを登録する自作プラグインの登録により解決する方法について記述する。

上手くいかないパターン

axiosを利用するAPIクラスを実装し、これをインポートして通信を行う。

plugins/axios.js

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/user.js:

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

nuxt-foncig.js

axiosプラグインを登録。

module.exports = {

  // ....

  plugins: [
    '~/plugins/axios',
  ],

  modules: [
    '@nuxtjs/axios',
  ],

  // ....

}

components/user/index.vue

<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と同様になる。

plugins/axios.js

変更無し。

api/apis/user.js

プラグインの格納位置を変更すると共にクラスから関数形式に変更。

export default axios => ({
  list() {
    return axios.get('/api/users')
      .then(data => data.data)
      .catch(err => {throw err})
  },
})

api/define.js

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) )

plugins/apiregister.js

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))
  })
}

nuxt-config.js

apiregisterプラグインを追加登録。

module.exports = {

  // ....

  plugins: [
    '~/plugins/axios',
    '~/plugins/apiregister',
  ],

  modules: [
    '@nuxtjs/axios',
  ],

  // ....

}

components/user/index.vue

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登録のせいか微妙に初期表示が遅くなる?

元ネタなど

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment