2021年版 Nuxt.js + axios (module) 外部API利用 CORS 回避
概要
Nuxt から 自前実装の外部APIを利用する際の実装について解説します。
解説記事はたくさんありますが、 @nuxtjs/axios
の公式ドキュメントと内容がマッチしていなかったり、古かったりするので、自身で実装して確認したものを、自分の理解とともに記載します。
なお、@nuxtjs/axios
モジュールを使わないほうが良いという認識はありますが、
今回直近の実装案件においては、そこまで開発規模が大きくなく、
自前実装すると逆にコードが増えるため、モジュールを使うことにしました。
そのうちモジュールを使わないパターンも書くかもしれませんが、
誰か書いていただけるとありがたいなーと思っています。
"@nuxtjs/axios": "^5.13.1"
"nuxt": "^2.15.5"
注意
target: 'static'
のnuxtアプリでは、proxyは利用できません。
参考資料
前提
今回は外部APIのエンドポイントが、https://api.example.com/v1
だった場合で、
解説をしていきます。
また、リクエストを出す側の Nuxt
アプリは、
http://localhost:3000
で起動しているとします。
Store (Vuex)
から axios
を使って外部APIを叩き、
取得したデータを state
に格納します。
全体像の把握
今回の実装で全体的なリクエストの流れとしては、以下のようになります。
-
this.$axios.get('/users')
でリクエストを出す。 -
axios
のprefix
オプションで、/api
がつきhttp://localhost:3000/api/users
にリクエストが出る -
/api
がついているパスへのリクエストをproxy
の対象として、target
に指定したURL (https://api.example.com
) +2
のパス/api/users
にpathRewrite
の指定が適応されて、/api
→/v1
に変換される。 - 最終的に
https://api.example.com/v1/users
にリクエストが出る。
各ファイルの記述
nuxt.config.js
この実装は nuxt.config.js
に正しく設定を記述できるかが肝です。
それさえできれば、各所でのリクエストの出し方は通常の @nuxtjs/axios
の使い方です。
modules
への追記と、別途 axios
proxy
の記述を行います。
{
modules: [
'@nuxtjs/axios',
],
axios: {
prefix: '/api',
proxy: true,
},
proxy: {
'/api/': {
target: `https://api.example.com`,
pathRewrite: {
'^/api/': '/v1/',
},
},
},
}
modules オプション
modules
には '@nuxtjs/axios' だけの記述で良いです。
@nuxtjs/proxy
は '@nuxtjs/axios
に含まれています。
実際記述しなくても動作します。
ただし、依存関係としてはインストールされている必要があります。
つまり要約すると、
- modules に
@nuxtjs/proxy
の記述は不要 -
package.json
に@nuxtjs/axios
は書かれている必要がある -
@nuxtjs/proxy
をあえて個別でアンインストールしたら動かないよ
ということです。
axios オプション
axios
オプションの prefix
によって、$axios.get
などで行うリクエストには常に、
/api
が自動で付与されるようになります。
// /api/users へリクエストになる
this.$axios.get('/users')
axios
オプションの proxy
は true
にします。
true
にしないみたいな記事もありましたが、公式にするように書かれていますし、
実際 proxy: true
を消すと、proxy
は使われません。
注意
baseURL
オプションを axios
には設定しません。
公式に proxy
を使う場合は、 baseURL
は使えないとあります。
実際、間違って baseURL
を設定している時うまく行かず、
外すと正常に動作しました。
proxy オプション
axios
オプションにてプレフィックス /api
を付けているので、
それを対象とするために、/api/: { オプション内容 }
という記載になっています。
target
に、外部APIのエンドポイントのホスト名までを指定します。
そして今回私のケースでは、外部APIには /v1
ついていますので、
pathRewrite
で、/api
を /v1
に置き換えています。
しかし、特に /v1
などつかない場合は、
'^/api/': '',
と記載します。
以上で、ほとんどの終わりです。
これで普通に this.$axios.get(...)
などで、
外部APIを叩くことが出来ます。
store/***.js
以下は、特殊なことはなく store
内での普通の使い方です。
該当箇所だけ記述して、省略しています。
export const state = () => ({
users: []
})
export const mutations = {
add(state, data) {
state.users = data
}
}
export const actions = {
async fetch({ commit, state }) {
if (!state.users.length) {
const res = await this.$axios.$get('/users')
commit('add', res.data)
}
},
}
確認方法
nuxt
コマンドを実行して、ローカルで起動した際に、
ターミナルに以下のように表示されていれば、設定できているということになります。
Discussion