Nuxt.jsでestat-APIのデータを取得するまで
estat-APIとは
政府統計の総合窓口e-Statで公表されている統計データを取得できるAPI
ユーザ登録
利用するためにはユーザ登録してアプリケーションIDを取得する必要がある
API機能を利用する際に、アプリケーションIDを送信する必要があります。
政府統計の総合窓口(e-Stat)のマイページにログインし、API機能(アプリケーションID発行)から、開発するアプリケーションごとにアプリケーションIDを取得してください。
アプリケーションID取得時に入力する名称、URL、概要は後から変更しても構いません。また、URLについては、公開サイトで利用しない場合は、ローカルアドレス(「http://test.localhost/」等)を入力してください。
クレジット表示
API機能を使用したサービスを公開する場合は、下記のクレジット表示が必要。
「このサービスは、政府統計総合窓口(e-Stat)のAPI機能を使用していますが、サービスの内容は国によって保証されたものではありません。」
使い方
公式サイトにあるとおり、リクエストURLからデータを取得。
// XMLの場合
http://api.e-stat.go.jp/rest/<バージョン>/app/getStatsData?<パラメータ群>
// JSONの場合
http://api.e-stat.go.jp/rest/<バージョン>/app/json/getStatsData?<パラメータ群>
例えば東京の老年人口割合[65歳以上人口]を取得したい場合、リクエストパラメータは下記。
http://api.e-stat.go.jp/rest/2.0/app/getStatsData?appId=<アプリケーションID>&statsDataId=C0020050213000&cdCat01=%23A03503
estat-APIを利用する準備
estatの利用者登録とappIdの取得
appIdを環境変数として利用
プロジェクト直下に.envファイルを作成して、取得したAPIキーをESTAT_APPIDとして記載しておく。
ESTAT_APPID = '○○○○○○○○○○○○○○○○○'
Nuxtv2.13以降ならdotenvを利用しなくても、Nuxtの標準機能で環境変数を利用できる。
公式サイトを参考にpublicRuntimeConfigを定義する。
publicRuntimeConfig: {
ESTAT_APPID: process.env.ESTAT_APPID,
},
環境変数は$configのグローバルに定義されるので、どこからでも呼び出し可能。
GitHub Actionsで環境変数を利用
GitHub Actionsでビルドする場合、プロジェクト内で設定した.envは反映されないので、別途設定する必要がある。
GitHubのリポジトリにseacretを設定する
公式ドキュメントを参考に、SECRET 情報を登録する。
- リポジトリのメインページから
Settings
項目を選択し、設定ページに飛ぶ。 - 左のサイドバーから
Secrets
を押下する。 -
New repository secret
ボタンを押下する。 -
Name
に SECRET 情報の名前ESTAT_APPIDを、Value
に SECRET 情報を入力する。 -
Add secret
ボタンを押下し、SECRET 情報を登録する。
workflowでseacretを読み込む
ワークフローのbuildセクションで、登録したSECRET 情報を呼び出す。
※詳しくは公式ドキュメント参照
jobs:
build:
runs-on: ubuntu-18.04
env:
RESAS_API_KEY: ${{ secrets.RESAS_API_KEY }}
nuxtjs/axiosのインストールと設定
APIを利用する場合、Promise ベースの HTTP クライアントである「axios」を利用することが多い。
ここでは、nuxt.js用のブラグイン「nuxt/axios」をインストールする。
インストール
yarn add @nuxtjs/axios
nuxt.config.js
で@nuxtjs/axiosを有効化する。
modules: [
"@nuxtjs/axios",
],
estat-APIを利用するときの共通処理
公式ドキュメントに従って、axiosの共通処理をプラグイン化する。
プラグインの作成
Nuxtプロジェクト内にplugins/estat.js
を作成。プラグインの詳細は公式ドキュメント参照。
import qs from 'qs';
export default function ({ $axios, $config }, inject) {
const api = $axios.create({
headers: {
common: {
Accept: 'application/json',
},
'Content-Type': 'application/json',
},
params: {
appId: $config.ESTAT_APPID,
},
paramsSerializer: (params) => {
return qs.stringify(params, { arrayFormat: 'comma' });
},
data: {},
})
api.setBaseURL(`https://api.e-stat.go.jp/rest/3.0/app/json/getStatsData`)
inject('estat', api)
}
パラメータの初期設定
axiosのリクエストパラメータのうち、共通で利用する値をセットする。
ここでは、appIdの値を環境変数から取得してセットしている。
params: {
appId: $config.ESTAT_APPID,
},
paramsSerializerオプションの設定
このままでは、例えばパラメータをcdArea:['28000',28100','28200']
とした場合に、下記のクエリパラメータが生成されるため、エラーとなる。
cdArea[]=28000&cdArea[]=28100&cdArea[]=28200
そこで、qsというライブラリを利用する。
paramsSerializer: (params) => {
return qs.stringify(params, { arrayFormat: 'comma' });
},
この結果、クエリパラメータは次のとおり生成される。
cdArea=28000&%2C28100&%2C28200
なお、qsを利用すると他の形にも生成可能。詳細は公式サイト参照。
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
// 'a[0]=b&a[1]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })
// 'a[]=b&a[]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
// 'a=b&a=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'comma' })
// 'a=b,c'
axios/proxyを利用してCORS回避
このままではeStat-APIのデータを取得できない。
下記のとおり、CORSのエラーが発生する。
Access to XMLHttpRequest at 'https://opendata.resas-portal.go.jp/?statsDataId=0000010101&cdArea=28000&cdCat01=A1101' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
そこで、proxyを利用してこのCORSエラーを回避する。
nuxt.config.js
でaxios/proxyを有効化して、proxy設定を追加する。
axios: {
proxy: true
},
proxy: {
'/json/': {
target: 'http://api.e-stat.go.jp/rest/3.0/app/json',
pathRewrite: {
'^/json/': '/',
},
},
},
これで、http://localhost:3000/json/
へのアクセスが
https://api.e-stat.go.jp/rest/3.0/app/json/
にリダイレクトされる。
plugins/estat.js
のBaseURLは次のとおり修正する。
api.setBaseURL(http://localhost:3000/json/getStatsData`)
開発環境と実行環境
このままでは、実行環境でもhttp://localhost:3000/
にアクセスしてしまうので、環境変数SITE_URLを設定して、開発環境と実行環境で使い分ける。
開発環境のURLは.env
に追記
SITE_URL = 'http://localhost:3000/'
実行環境のURLは、前述したとおりGitHubのseacretを設定する。
共通関数として利用
これまでをまとめると、最終的にplugins/estat.js
は次の形になる。
import qs from 'qs';
export default function ({ $axios, $config }, inject) {
const api = $axios.create({
headers: {
common: {
Accept: 'application/json',
},
'Content-Type': 'application/json',
},
params: {
appId: $config.ESTAT_APPID,
},
paramsSerializer: (params) => {
return qs.stringify(params, { arrayFormat: 'comma' });
},
data: {},
})
api.setBaseURL(`${$config.SITE_URL}json/getStatsData`)
inject('estat', api)
}
最後に、injectで関数を共通処理化している。これで別のコンポーネントからthis.$estatで呼び出すことができる。
プラグインの有効化
nuxt.config.js
でプラグインを有効化。
plugins: [
{ src: '@/plugins/estat', ssr: true, },
],
Nuxt.jsでeStat-APIのデータを取得
axiosの基本的な使い方(GET)
公式ドキュメントにあるとおり、クエリパラメータを指定する方法が2種類ある。
axios.getに指定するURLに直接記述する方法
axios.get('/user?ID=12345')
axios.getの第2引数に、オプション指定する方法
axios.get('/user', {
params: {
ID: 12345
}
})
ここでは2番目の方法を利用する。
estat-API概要
政府統計の総合窓口eStatから入手したい統計表データを検索し、APIを取得する。
今回は社会・人口統計体系 A 人口・世帯より、都道府県の総人口データを取得する。
パラメータの設定
兵庫県の総人口データを取得する場合、パラメータは次のとおりとなる。
A1101
が総人口、A110101
が男性人口、A110102
が女性人口。
estatParams() {
return {
statsDataId: '0000010101',
cdArea: ['28000'],
cdCat01: ['A1101', 'A110101', 'A110102'],
}
},
データの取得
共通化した this.$estatのgetメソッドを利用する。
これで、estatResponse
に結果が格納される。
data() {
return {
estatResponse: null,
}
},
async fetch() {
const params = this.estatParams
const { data } = await this.$estat.get(null, { params })
this.estatResponse = data
},
composition-apiの場合
プラグインではなく、composition-apiのcomposition関数として利用する場合。
import { reactive, toRefs } from '@nuxtjs/composition-api'
import qs from 'qs'
export const useEstatApi = (axios, params) => {
const state = reactive<baseState>({
response: {},
otherError: null,
isLoading: false,
})
// const { $axios } = useContext()
const getData = async () => {
const url = 'getStatsData'
const api = axios.create({
headers: {
common: {
Accept: 'application/json',
},
'Content-Type': 'application/json',
},
params: {
appId: process.env.ESTAT_APPID,
},
paramsSerializer: (params) => {
return qs.stringify(params, { arrayFormat: 'comma' })
},
// mode: 'cors',
withCredentials: true,
data: {},
})
api.setBaseURL(`${process.env.BASE_URL}/json/`)
state.isLoading = true
const res = await api.$get(url, { params })
return res
}
return {
...toRefs(state),
getData,
}
}
呼び出し側は次の通り。
const estatResponse = ref<EstatResponse>()
const { $axios } = useContext()
const { fetch } = useFetch(async () => {
const params = {}
estatResponse.value = await useEstatApi($axios, params).getData()
})
fetch()
Nuxt(SSP)とGCPで作成したアプリ
サイト
コード
Discussion