Edited at

加古川市オープンデータ API 利用チュートリアル

More than 1 year has passed since last update.


はじめに

加古川市オープンデータ API は、いわゆる REST API になっていて、追加で OAuth2 を使います。ちょうど facebook API や twitter API などと同じような構成です。利用する際の処理の流れは大きく分けて、OAuth2 の部分と、REST API の部分の二つにわかれます。


OAuth2

OAuth2 は少し難しく見えます(そして実際ややこしいです)が、OAuth2 の処理が終わった後、最終的には「アクセストークン」が発行されます。

なにはともあれ OAuth2 の処理を行うには、決められた手順を踏まないとできません。OAuth2 で使用する様々な文字列は、「利用申請兼通知書」で申請すると得られます。「利用申請兼通知書」ですが、「アカウントの登録」と「アプリの登録」の二つのパートがあります。初回に「アカウント発行」のみ行い、後で「アプリの登録」を行うということもできるはずです。とりあえずデータを閲覧したいというだけであれば、「アカウントの発行」のみで大丈夫です。どうやればいいのか十分わかっている場合は、両方同時に申請してもよいでしょう。

https://opendata-api-kakogawa.jp/odp/contact/

「利用申請兼通知書」のExcelシートの送付ですが、これはウェブのフォームで送付することができます(もちろん書面で送付することもできます)。必要な項目を記入して、加古川市の「スマイルメール」の送付フォームで添付ファイルとして送信してください。スマイルメールの件名は「加古川市オープンデータAPI 利用申請書兼通知書」と記入するとよいでしょう。

https://www.smilemail-kakogawa.jp/form/index.php?section_cd=1006

OAuth2 は様々な用途に汎用的に使えるように整備されてきたため、登場人物がたくさん出てきます。Authorization Code Grant が推奨される方法とされていますが、それが唯一の正解というわけではありません。自分が思い描いている形がどこに着地するかは、一度考えてみるとよいでしょう。

OAuth2 のガイドとしては「データ利活用基盤サービス(FIWARE)アプリケーション開発ガイド 認証認可編」が参考になります(注1)。チュートリアルでは「アクセストークン」が得られた後の処理方法について説明します。


データの取得

curl でデータを取得してみます。ここでは「アクセストークン」を仮に 16b1f828-cbb2-4bde-a066-946594e01dc5 としています。実際に得られたものに置き換えて試してみてください。

curl -v "https://api.opendata-api-kakogawa.jp/orion/v1.0/queryContext" \

-X POST \
--header "Authorization: Bearer 16b1f828-cbb2-4bde-a066-946594e01dc5" \
--header "Content-type: application/json" \
--data '{"entities":[{"isPattern":"true","id":".*"}]}'

加古川市オープンデータ API で採用されている fiware-orion の NGSI v1 は少し変わった流儀をしていて、問い合わせのクエリで条件を request body で POST 送信します(v2 では GET に改められています)(注2)。

上の例は最小の例です。条件を追加すると絞り込みができます。isPattern が true の場合は、id に正規表現を指定します。fiware orion では、この正規表現は POSIX 正規表現で、glibc の拡張正規表現が使えます。つまり .* で全てにマッチします。

jq コマンドを通して整形すると結果が見やすくなります。ID だけ並べてみましょう。

$ curl -s https://api.opendata-api-kakogawa.jp/orion/v1.0/queryContext \

-X POST \
--header "Authorization: Bearer 16b1f828-cbb2-4bde-a066-946594e01dc5" \
--header "Content-type: application/json" \
--data '{"entities":[{"isPattern":"true","id":".*"}]}' \
| jq .contextResponses[].contextElement.id
"jp.opendata-api-kakogawa.AEDFacilities.Shikanren.1"
"jp.opendata-api-kakogawa.Transportaion.KakobusHigashikakogawa.1"
"jp.dev-necjfiware.PublicFacilities.Churinjo.1"
"jp.dev-necjfiware.Tourism.KanbeYukari.1"
"jp.dev-necjfiware.ChildcareCenter.1"
"jp.dev-necjfiware.BarrierFreeFacilities.1"
"jp.opendata-api-kakogawa.DisasterManagementFacilities.KinkyuHinanbashoHinanjo.1"
"jp.dev-necjfiware.CareOffices.Fukugou.1"
"jp.opendata-api-kakogawa.CareOffices.Fukugou.1"
"jp.opendata-api-kakogawa.ChildcareCenter.1"
"jp.opendata-api-kakogawa.BarrierFreeFacilities.1"
"jp.opendata-api-kakogawa.PublicFacilities.Churinjo.1"
"jp.opendata-api-kakogawa.Tourism.KanbeYukari.1"
"jp.opendata-api-kakogawa.FloodHazardMap.ShinsuiJisseki.1"
"jp.opendata-api-kakogawa.LandslideHazardMap.KyukeisyaHigaiSoutei.1"
"jp.opendata-api-kakogawa.LandslideAreaHazardMap.Sanpuku.1"
"jp.opendata-api-kakogawa.PondHazardMap.Tameike.1"
"jp.opendata-api-kakogawa.DisasterManagementFacilities.Tsunami.1"
"jp.opendata-api-kakogawa.DisasterManagementFacilities.Hinanjo.1"
"jp.opendata-api-kakogawa.DisasterManagementFacilities.KinkyuHinanbasho.1"

意外と少ないですね。実は一度に取得できる件数はデフォルトで 20 件に絞られています。query string に detail=on を追加すると全体の件数も分かるようです。

$ curl -s https://api.opendata-api-kakogawa.jp/orion/v1.0/queryContext \

-X POST \
--header "Authorization: Bearer 16b1f828-cbb2-4bde-a066-946594e01dc5" \
--header "Content-type: application/json" \
--data '{"entities":[{"isPattern":"true","id":".*"}]}' \
| jq .errorCode.details
"Count: 1649"

このような処理は一般的に「ページネーション」と呼ばれます。fiware-orion のドキュメントもありますので、適宜ページを繰って読み出してください(注3)。

https://fiware-orion.readthedocs.io/en/master/user/pagination/index.html#pagination-using-ngsiv1


データの中身

NGSI ではデータの形が決まっていて、「あるデータ」は「ID で識別され、「属性を複数持つ」という形です。試しに 1 つだけ取り出してみましょう(説明のため内容を若干編集しています)。

$ curl -s "https://api.opendata-api-kakogawa.jp/orion/v1.0/queryContext?limit=1" \

-X POST \
--header "Authorization: Bearer 16b1f828-cbb2-4bde-a066-946594e01dc5" \
--header "Content-type: application/json" \
--data '{"entities":[{"isPattern":"true","id":".*"}]}'
| jq
{
"contextResponses": [
{
"contextElement": {
"type": "AEDFacilities",
"isPattern": "false",
"id": "jp.opendata-api-kakogawa.AEDFacilities.Shikanren.1",
"attributes": [
{
"name": "住所",
"type": "xsd:string",
"value": "加古川町本町194"
},
{
"name": "名称",
"type": "xsd:string",
"value": "中央消防署"
}
]
},
"statusCode": {
"code": "200",
"reasonPhrase": "OK"
}
}
]
}

上記の例では jp.opendata-api-kakogawa.AEDFacilities.Shikanren.1 が ID で、「住所」と「名称」という属性を持っています。

加古川オープンデータのサイトには複数のデータセットが登録されていますが、これらは同列に混ぜて取り出すことができるようになっています。取得の際に条件を追加して、例えば {"type":"AEDFacilities"} を追加するときれいに 1 つのデータセットを抜き出せます。

https://opendata-api-kakogawa.jp/ckan/dataset?res_format=ngsi10


用語 : Broker と context

fiware orion は data broker つまり、データを右から左に伝搬させる通知機能を持っています。一般的に言われる MQTT, AMQP や kafka で登場する broker と同じものです。NGSI では、通知を受け取るには通知を受け取る HTTP エンドポイントを subscribe します。NGSI-10 の notifyContext を使います。fiware orion はデータ登録先の機能を持ちますし、データの更新をトリガーとして通知を伝搬するブローカーとしても動作します。

これを試すには通知を受け取るサーバが必要になります。GCP の無料インスタンスなどを使って実験するとよいでしょう。次に subscribe と unsubscribe の例を示します。

$ curl "https://api.opendata-api-kakogawa.jp/orion/v1.0/subscribeContext" \

-X POST \
--header "Authorization: Bearer 16b1f828-cbb2-4bde-a066-946594e01dc5" \
--header "Content-type: application/json" \
--data '{"entities":[{"isPattern":"true","id":".*"}],
"reference":"http://example.com/v1/notify"}'

| jq
{
"subscribeResponse": {
"subscriptionId": "5b35ee3b0c736c3c77d0df75",
"duration": "PT24H"
}
}

$ curl "https://api.opendata-api-kakogawa.jp/orion/v1.0/unsubscribeContext" \

-X POST \
--header "Authorization: Bearer 16b1f828-cbb2-4bde-a066-946594e01dc5" \
--header "Content-type: application/json" \
--data '{"subscriptionId":"5b35ee3b0c736c3c77d0df75"}'
| jq
{
"subscriptionId": "5b35ee3b0c736c3c77d0df75",
"statusCode": {
"code": "200",
"reasonPhrase": "OK"
}
}

上記の例では、有効期間を省略しました。デフォルトでは PT24H の24時間になるようです。期限が切れる前に定期的にアップデートしましょう。この期間が都合が悪い時は、subscribe 時に duration パラメータを指定しましょう。ISO8601 の表記方法なので、例えば P1M は P = period, 1M = 1 month となります(注3)。

fiware orion へのデータ更新は、単なる登録データの更新のように見えます。fiware orion から離れて、もう少し視点を高く持って NGSI の概念をもう少し広く見ると、データの登録をスイッチのオンオフのように考えることもできます。テレビを指し示すデータに "ON" を登録すると、実際のスイッチにも伝わってテレビが "ON" になる、といった具合です。このため NGSI の用語では、このデータのことを単なるデータとは呼ばずに、意識的に「コンテキスト」と呼んでいます。「コンテキストに値をセットする」と言えば、理解がしやすくなります。対比のためにいくつか例を挙げると、「(コンピュータ用語で)レジスタに値をセットする」だったり「(ネットワーク機器用語で)snmpで値をセットする」だったりします。


認証

実は OAuth2 自体は認証の仕組みではありません。一般的に言われている認証は、内部が複数の機能に分割されて Authentication, Authorization, Accounting の 3 つに分割されます。Authentication は「誰であるか」を特定する認証、Authorization は「許可を与える」承認、Accounting は「利用状態の管理」です。OAuth2 自体はこのうちの Authorization の枠組みです。

加古川オープンデータの申請書では AAA のすべてが入っていますが、これをそのままエンドユーザに提供する必要はありません。アプリケーションの用途に応じて、追加で AAA の仕組みを設計して使うとよいでしょう。


環境構築

Windows 10 では次の手順が簡単です


  • Windows Store から Ubuntu をインストール

  • apt-get update

  • apt-get install -y curl jq


注釈


注1

加古川市で公開している開発ガイドはとても役に立ちます。 http://www.city.kakogawa.lg.jp/soshikikarasagasu/kikakubu/jouhouseisakuka/opendata/1528499081092.html

OAuth2 の原典は RFC 6749 を参照してください。https://tools.ietf.org/html/rfc6749


注2

残念ながら十分に記述された仕様は存在しませんが、次のドキュメントが手掛かりになります。


注3


追記

6/30 土曜日に申請書送付して、7/4 水曜日にアカウント発行されました。おおよその目安として。添付ファイルをパスワード付き zip ファイルにくるんでメール、パスワードを別途送信、というフローを使っている様子なので、備考欄にメールアドレス以外の連絡手段を書いておくとよいのかも……?