Nuxt.jsでeStat-APIからデータを取得するまで

e-Stat-APIとは

政府統計の総合窓口e-Statで公表されている統計データを取得できるAPI

ユーザ登録

利用するためにはユーザ登録してアプリケーションIDを取得する必要がある

API機能を利用する際に、アプリケーションIDを送信する必要があります。
政府統計の総合窓口(e-Stat)のマイページにログインし、API機能(アプリケーションID発行)から、開発するアプリケーションごとにアプリケーションIDを取得してください。
アプリケーションID取得時に入力する名称、URL、概要は後から変更しても構いません。また、URLについては、公開サイトで利用しない場合は、ローカルアドレス(「http://test.localhost/」等)を入力してください。

クレジット表示

API機能を使用したサービスを公開する場合は、下記のクレジット表示が必要。

使い方

公式サイトにあるとおり、リクエストURLからデータを取得します。

1
2
3
4
5
// XMLの場合
http://api.e-stat.go.jp/rest/<バージョン>/app/getStatsData?<パラメータ群>

// JSONの場合
http://api.e-stat.go.jp/rest/<バージョン>/app/json/getStatsData?<パラメータ群>

例えば東京の老年人口割合[65歳以上人口]を取得したい場合、リクエストパラメータは下記のとおりとなる。

1
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として記載しておく。

1
ESTAT_APPID = '○○○○○○○○○○○○○○○○○'

Nuxtv2.13以降ならdotenvを利用しなくても、Nuxtの標準機能で環境変数を利用できる。

公式サイトにあるとおり、**nuxt.config.jspublicRuntimeConfig**を定義する。

1
2
3
publicRuntimeConfig: {
ESTAT_APPID: process.env.ESTAT_APPID,
},

環境変数は$configのグローバルに定義されるので、どこからでも呼び出し可能。

GitHub Actionsで環境変数を利用

GitHub Actionsでビルドする場合、プロジェクト内で設定した.envは反映されないので、別途設定する必要がある。

GitHubのリポジトリにseacretを設定する

公式ドキュメントを参考に、SECRET 情報を登録する。

  1. リポジトリのメインページからSettings項目を選択し、設定ページに飛ぶ。
  2. 左のサイドバーからSecretsを押下する。
  3. New repository secretボタンを押下する。
  4. Nameに SECRET 情報の名前ESTAT_APPIDを、Valueに SECRET 情報を入力する。
  5. Add secretボタンを押下し、SECRET 情報を登録する。

workflowでseacretを読み込む

ワークフローのbuildセクションで、登録したSECRET 情報を呼び出す。
※詳しくは公式ドキュメント参照

netlify.yml#L8-L12link
8
9
10
11
12
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」をインストールする。

インストール

1
yarn add @nuxtjs/axios

nuxt.config.jsで@nuxtjs/axiosを有効化する。

nuxt.config.js#L57-L59link
57
58
59
modules: [
"@nuxtjs/axios",
],

estat-APIを利用するときの共通処理

公式ドキュメントに従って、axiosの共通処理をプラグイン化する。

プラグインの作成

Nuxtプロジェクト内にplugins/estat.jsを作成。プラグインの詳細は公式ドキュメント参照。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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の値を環境変数から取得してセットしている。

estat.js#L11-L13link
11
12
13
params: {
appId: $config.ESTAT_APPID,
},

paramsSerializerオプションの設定

このままでは、例えばパラメータをcdArea:['28000',28100','28200']とした場合に、下記のクエリパラメータが生成されるため、エラーとなる。

1
cdArea[]=28000&cdArea[]=28100&cdArea[]=28200

そこで、qsというライブラリを利用する。

estat.js#L14-L16link
14
15
16
paramsSerializer: (params) => {
return qs.stringify(params, { arrayFormat: 'comma' });
},

この結果、クエリパラメータは次のとおり生成される。

1
cdArea=28000&%2C28100&%2C28200

なお、qsを利用すると他の形にも生成可能。詳細は公式サイト参照。

1
2
3
4
5
6
7
8
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のエラーが発生する。

1
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設定を追加する。

nuxt.config.js#L84-L95link
84
85
86
87
88
89
90
91
92
93
94
95
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に追記

1
SITE_URL = 'http://localhost:3000/'

実行環境のURLは、前述したとおりGitHubのseacretを設定する。

共通関数として利用

これまでをまとめると、最終的にplugins/estat.jsは次の形になる。

estat.jslink
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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で呼び出すことができる。

estat.js#L23link
23
inject('estat', api)

プラグインの有効化

nuxt.config.jsでプラグインを有効化。

nuxt.config.js#L38link
38
{ src: '@/plugins/estat', ssr: true, },

Nuxt.jsでeStat-APIのデータを取得

axiosの基本的な使い方(GET)

公式ドキュメントにあるとおり、クエリパラメータを指定する方法が2種類ある。

axios.getに指定するURLに直接記述する方法

1
axios.get('/user?ID=12345')

axios.getの第2引数に、オプション指定する方法

1
2
3
4
5
axios.get('/user', {
params: {
ID: 12345
}
})

ここでは、②の方法を利用する。

estat-API概要

政府統計の総合窓口eStatから入手したい統計表データを検索し、APIを取得する。
今回は社会・人口統計体系 A 人口・世帯より、都道府県の総人口データを取得する。

パラメータの設定

兵庫県の総人口データを取得する場合、パラメータは次のとおりとなる。

A1101が総人口、A110101が男性人口、A110102が女性人口。

PopulationPref.vue#L64-L70link
64
65
66
67
68
69
70
estatParams() {
return {
statsDataId: '0000010101',
cdArea: ['28000'],
cdCat01: ['A1101', 'A110101', 'A110102'],
}
},

データの取得

共通化した this.$estatのgetメソッドを利用する。
これで、estatResponseに結果が格納される。

PopulationPref.vue#L45-L50link
45
46
47
48
49
50
async fetch() {
const params = this.estatParams
const { data } = await this.$estat.get(null, { params })
console.log(data)
this.estatResponse = data
},