Drogonを使って行政のAPIを叩いてみよう
皆様こんにちは、あるいはこんばんは、みじんこきなこです。
前回の記事投稿からすっかり時間が空いてしまいましたが、
今回はDrogonのHttpClientクラスを使用して行政のAPIを叩いてデータを取得してみます。
今回使用するHttpClientクラスは、2022年11月時点では公式のWikiに詳細な使用方法の解説が存在しておらず、
使用するには若干のソースコード読解とDocsforgeで作成されたリファレンスの参照が必要となります。
とはいえ、基本的な設計思想は以前の記事で紹介したDbClientクラスと共通しているので、それほど難しいものではありません。
事前準備
今回のテーマ、行政のAPIを叩くにあたり、対象として内閣府の出している地域経済分析システム、RESASのAPIを使用します。
RESAS-APIのサイトでユーザ登録して、APIキーを取得しておいてください。
リファレンスを参照するとわかりますが、日本という国の経済についてかなり多角的な分析が可能な情報が取得できます。
年に1度このAPIを使用したサービスのコンテストなども行われているので、なにか面白いことを思いついたときは応募してみても良いかもしれません。
今回はこれらのAPIのうち、パラメータと返ってくるデータが単純な、輸出品目統計分類コード(HSコード)の小分類を取ってくるAPIを使用します。
いつもの準備
まずはプロジェクトとコントローラを作成しましょう。
作成方法は過去のこの記事で詳しく解説しています。
今回は特に表示する画面もないので、Viewは作成しません。
待受ポートはDebian系Linuxでは80を使うと実行時に管理者権限が必要となり面倒ですので、今回は50080としています。
HttpsClientクラスを使う
本来的な使途でいけば、HttpClientクラスは自身が作成したWebアプリをテストするテストフレームワークで使用することを想定されたもののようです。
そのため、これまでの記事で紹介してきた機能と異なり、HttpClientクラスはただ生成しただけのコントローラから使用することはできません。
HttpClientを使用するには、以下のヘッダファイルをインクルードしてリンクしてやる必要があります。
drogon/HttpClient.h
drogonフレームワークの機能ですので、他のモジュールと同じく < > でインクルードしてやると良いでしょう。
#include <drogon/HttpClient.h>
C++で他のファイルを導入する際に使用する#includeのパスの指定には、""と<>のパターンがありますが、その違いはインクルードディレクトリの検索順の違いですので、""であっても問題ありません。
※厳密にはビルド速度やプリコンパイル時のマシン負荷に差が出ることになりますが、何千ものファイルを経由してリンクするのでもない限り体感できるほどの差は出ません。
HttpControllerクラス
getHScode.h
#pragma once
#include <drogon/HttpController.h>
using namespace drogon;
class getHScode : public drogon::HttpController<getHScode>
{
public:
METHOD_LIST_BEGIN
METHOD_ADD(getHScode::get, "/", Get); // path is /getHScode/{arg2}/{arg1}
METHOD_LIST_END
void get(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback);
};
#include "getHScode.h"
#include <drogon/HttpClient.h>
void getHScode::get(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback)
{
auto client = drogon::HttpClient::newHttpClient(
"https://opendata.resas-portal.go.jp/"
);
auto api_path = "/api/v1/tradeInfoItemTypes/narrow";
auto request = drogon::HttpRequest::newHttpRequest();
request->setPath(api_path);
request->setMethod(drogon::HttpMethod::Get);
/*auto api_key = "[ご自身のAPIキーをここに書いてください]";*/
request->addHeader("X-API-KEY",api_key);
request->setParameter("itemCode1", "1");
auto result = client->sendRequest(request);
auto response = drogon::HttpResponse::newHttpResponse();
response->setBody(
result.second
.get()
->getBody()
.data()
);
callback(response);
}
細かい解説
HttpClientクラス初期化
HttpClientクラスは、初期化時に接続対象となるAPIサーバのドメインを指定してやる必要があります。
今回は対象がRESASなので、以下のようになります。
auto client = drogon::HttpClient::newHttpClient(
"https://opendata.resas-portal.go.jp/"
);
APIパスとリクエストの設定
APIパスとその叩き方は、drogon::HttpRequestクラスを使用して管理します。 ドメインはサーバに、APIパスはサーバが提供するプログラムに紐づくものなので、 クライアントとしてはドメイン、リクエストとしてはAPIパスを管理するという構造が意味論的にも美しく、個人的に大好きです。
auto api_path = "/api/v1/tradeInfoItemTypes/narrow";
auto request = drogon::HttpRequest::newHttpRequest();
request->setPath(api_path);
request->setMethod(drogon::HttpMethod::Get);
APIキーの使い方
APIキーの設定方法については、RESAS APIのリファレンスの中でHTTPヘッダに、X-API-KEY というキー名で設定してねと記載があります。
なのでDrogonのHttpClientクラスで使用する場合は以下のように設定します。
/auto api_key = "[ご自身のAPIキーをここに書いてください]";/
request->addHeader("X-API-KEY",api_key);
request->setParameter("itemCode1", "1");
APIの実行
HttpClientクラスはDbClientクラスと同様、接続対象から得た結果を処理するためのインターフェースをいくつか持っています。 今回は同期で問い合わせ、戻り値で結果を取る同期インターフェースを使用します。
auto result = client->sendRequest(request);
結果をそのまま自身のクライアントに返す
HttpClientの同期実行インターフェースで返ってくる結果は、
httpコードと実際のデータのpairコンテナとなっています。
今回はhttpコードについては考えず、データとして返ってきたレスポンスボディを、そのまま接続してきたクライアントに返してしまいます。
auto response = drogon::HttpResponse::newHttpResponse();
response->setBody(
result.second
.get()
->getBody()
.data()
);
callback(response);
実行してみる
最後に今回作成したプロジェクトをビルドして、実行してみます。
ビルド方法はこちらの記事を参照してください。
http://localhost:50080/getHScode/
にアクセスしてみて、実際に取得したHSコード一覧がJSONで表示されれば成功です。
さいごに
今回はDrogonのHttpClientクラスの使い方について解説を行いました。
Drogonフレームワークはアプリケーションサーバとして機能するものではありますが、クライアントからのリクエストに応じて自身以外のサーバが提供するAPIを使用することで、様々なAPIをマッシュアップしたサービスを作ることができます。
また、今回は透過的にRESAS APIからのレスポンスをクライアントに返しましたが、Drogonの高速で駆動する特性を活かし、フィルタ機能や値の検証などを行うことで、低レイテンシで簡易な防壁として利用することもできるでしょう。
皆様もぜひとも使ってみてください。