📈

Nuxt.jsでestat-APIのデータを取得するまで

2022/03/06に公開

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

.env
ESTAT_APPID = '○○○○○○○○○○○○○○○○○'

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

公式サイトを参考にpublicRuntimeConfigを定義する。

nuxt.config.js
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 情報を呼び出す。
※詳しくは公式ドキュメント参照

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を有効化する。

nuxt.config.js
 modules: [
    "@nuxtjs/axios",
  ],

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

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

プラグインの作成

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

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

nuxt.config.js
  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は次のとおり修正する。

plugins/estat.js
api.setBaseURL(http://localhost:3000/json/getStatsData`)

開発環境と実行環境

このままでは、実行環境でもhttp://localhost:3000/にアクセスしてしまうので、環境変数SITE_URLを設定して、開発環境と実行環境で使い分ける。

開発環境のURLは.envに追記

.env
SITE_URL = 'http://localhost:3000/'

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

共通関数として利用

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

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でプラグインを有効化。

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関数として利用する場合。

composition/useEstat.ts
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で作成したアプリ

サイト

https://statistics-hyogo.com/

コード

https://github.com/dicechick373/statistics-hyogo

Discussion