Old Sunset Days

Hugoで外部APIで取得したJSONデータを利用する

日付 タグ hugo カテゴリ hugo

目次

HugoでData-Driven Content機能を利用する

記事生成時で取得したデータになってはしまうが(ページ表示の毎アクセス時ではない)、Hugoで外部APIのURLで取得したCSVやJSONデータを利用できるData-Driven Content機能があるので使ってみた。

https://gohugo.io/templates/data-templates - Data Templates

Data-Driven Content In addition to the data files feature, Hugo also has a “data-driven content” feature, which lets you load any JSON or CSV file from nearly any resource.

Data-driven content currently consists of two functions, getJSON and getCSV, which are available in all template files.

一般公開されているWEB APIを利用してテスト

今回はサーマルコンポーネント株式会社のネットワークサービス「ThNI」スタッフによって個人・法人・商用・非商用問わず無料で提供してくれている郵便番号から住所を検索するAPIを使って、実際に動作を検証してみる。

http://project.iw3.org/zip_search_x0401/ - ZIP SEARCH API SERVICE 「JIS X0401」対応版ver 1.0.0

サンプル例としてIW3 PROJECTのページで紹介されている以下の例でテスト。

http://api.thni.net/jzip/X0401/JSON/郵便番号上3桁の数値/郵便番号下4桁の数値.js

郵便番号 => 住所を返してくれるWEB APIだ。

まずはAPIの挙動そのものをIW3 PROJECTのページにあるサンプルを例としてcurlコマンドで呼び出して返り値をチェックしてみる。

$ curl http://api.thni.net/jzip/X0401/JSON/064/0941.js
{ "state":"1", "stateName":"北海道", "city":"札幌市中央区", "street":"旭ケ丘" }

このようなフォーマットでデータが返ってくる。 このデータをHugoでData-Driven Contentを利用して取得できるかテストしてみよう。

Shortcode呼び出しを作成

Data-Driven Contentは記事のMarkdownファイルではなく、HTMLで記述する部分で機能するものであるため、 Shortcodeを作ってその中に記述するのが良いだろう。

HugoでのShortcodeがどんなものかは以前のブログ記事をチェックして欲しい。
( ==> Hugoでemoji絵文字 )

layouts/shortcodes/zipaddress.html

{{ $dataJ := getJSON "http://api.thni.net/jzip/X0401/JSON/" (.Get 0) "/" (.Get 1) ".js" }}
<ul>
  <li>state = {{ $dataJ.state}}</li>
  <li>stateName = {{ $dataJ.stateName}}</li>
  <li>city = {{ $dataJ.city}}</li>
  <li>street = {{ $dataJ.street}}</li>
</ul>

ブログ記事のMarkdown中で

{{< zipaddress “064” “0941” >}}

とすると表示上Shortcodeで変換されて

  • state = 1
  • stateName = 北海道
  • city = 札幌市中央区
  • street = 旭ケ丘
となる。shortcodeに渡す引数を変えると対応するレスポンスJSONが変わるので結果も変わる。

例えば、上野駅なら郵便番号上3桁の数値=110、郵便番号下4桁=0005なので、
ブログ記事のMarkdown中で

{{< zipaddress “110” “0005” >}}

とすると表示上Shortcodeで変換されて

  • state = 13
  • stateName = 東京都
  • city = 台東区
  • street = 上野
となる。動作としては想定通りの動作になった。

ただし、これはページ閲覧のたびに毎回データが取得されなおされるのではなく、Hugoはあくまでも静的なサイトジェネレーターであるので、ページがビルドされる時に取得されることに留意する必要がある。

またページがビルドされる時にも一度取得されたJSONデータがあると、データがキャッシュされて再利用されるのでそこについても注意が必要だ。

Data-Driven Contentのデータキャッシュ

Data-Driven Contentでは一度取得されたデータは公式サイトの説明にあるようにキャッシュされる。

Cache URLs

Each downloaded URL will be cached in the default folder $TMPDIR/hugo_cache/.
The variable $TMPDIR will be resolved to your system-dependent temporary directory. With the command-line flag –cacheDir, you can specify any folder on your system as a caching directory. You can also set cacheDir in the main configuration file. If you don’t like caching at all, you can fully disable caching with the command line flag –ignoreCache.

hugoに--ignoreCacheオプションを渡せば、キャッシュされないが、デフォルトでは一旦取得した結果は $TMPDIR/hugo_cache/以下に保存されるようだ。$TMPDIRはシステムや環境によってディレクトリは違ってくる。

先ほどのテストをローカルのMac環境で行った時には、通常の

$ hugo server

でサーバー起動してビルドが走った際に、

$ ls $TMPDIR/hugo_cache/my-blog/filecache/getjson/
37b028226e2772293a17eef0aa560bea	93dbbbedf24afc25a869d978fb0c5f24
$ cat $TMPDIR/hugo_cache/my-blog/filecache/getjson/37b028226e2772293a17eef0aa560bea
{ "state":"1", "stateName":"北海道", "city":"札幌市中央区", "street":"旭ケ丘" }

上記に取得したJSONがキャッシュされた。

キャッシュのデフォルトディレクトリは、

https://gohugo.io/getting-started/configuration/#configure-file-caches - Configure File Caches

に書いてあるように、config.tomlに以下のデフォルト値が設定されているのと同じ状態となる。

[caches]
  [caches.assets]
    dir = ":resourceDir/_gen"
    maxAge = -1
  [caches.getcsv]
    dir = ":cacheDir/:project"
    maxAge = -1
  [caches.getjson]
    dir = ":cacheDir/:project"
    maxAge = -1
  [caches.images]
    dir = ":resourceDir/_gen"
    maxAge = -1
  [caches.modules]
    dir = ":cacheDir/modules"
    maxAge = -1

You can override any of these cache settings in your own config.toml.

キャッシュのディレクトリを変更したいなら、config.tomlで設定をすれば変更が可能である。

以上、今回はJSONでのデータ取得について見てきたが、CSV形式のデータについても同様に扱うことが可能である。