Help us understand the problem. What is going on with this article?

加古川市オープンデータ 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 ファイルにくるんでメール、パスワードを別途送信、というフローを使っている様子なので、備考欄にメールアドレス以外の連絡手段を書いておくとよいのかも……?

kwi
iij
日本のインターネットを支えてきたIIJ。現在もその先もイニシアティブをとり続けます。
https://www.iij.ad.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away