Java クライント開発における Web API の実装アプローチ:その2 一般的なREST API編
それでは、今回から実際にそれぞれのWeb APIリクエストの実装アプローチを見ていきたいと思います。
最初はベーシックかつ、ふんわりとした取り決めである REST API から。
最初の記事はこちらから。
RESTについておさらい
ここではあまり多く語りませんが、REST はプロトコルや規約ではなく、あくまで Web API の設計思想、ソフトウェアアーキテクチャの一つであるという点です。
REST = Representational State Transfer
Representational State Transfer (REST) は、ウェブのような分散ハイパーメディアシステムのためのソフトウェアアーキテクチャのスタイルのひとつである。
引用元:Wikipedia REST
以下の4つの原則に従った Web API アーキテクチャをREST ful と呼んだりしますね。
Stateless:ステートレスなクライアント/サーバプロトコル Uniform Interface:すべての情報(リソース)に適用できるHTTPメソッドの定義 Addressability:リソースを一意に識別する「汎用的な構文(URL)」の定義 Connectability:アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディア(リソースリンク)の使用」
ただ、今回の記事では REST の原則には従っているが、それ以外の仕様に準拠しているわけではない、普遍的かつドキュメント以上のものが提供されていない Web API のことを示すこととしています。(これは別に REST を卑下しているわけではなく、今後のAPIスタイルとの比較のためです)
対象の REST API と前提条件
対象とする Web API は CData API Server を使って開発したものを利用します。
ODataプロトコルベースで、Swagger(OpenAPI)ドキュメントを公開していますが、特に今回は OData や Swagger であることを意識しません。
あくまでドキュメント以上のものは無い(SDKなども含めて)、という前提に立ちます。
ですので、シンプルに Java のオープンソースライブラリを使ってアクセスします。
APIアクセス用のトークンは、要望があれば公開する予定です。
操作はシンプルに注文データ(orders)と注文明細データ(order_details)を取得して結合したものをコンソールで出力するというものです。
利用ライブラリ
Java から API へのアクセスについては「OkHttpClient」と「GSON」、2つのライブラリを使用しました。
・OkHttpClient
・GSON
実装コード
以下のサイトで公開しています。
package com.company; import com.google.gson.Gson; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import java.util.List; import java.util.stream.Collector; import java.util.stream.Collectors; public class Main { public static final String url = "http://cdatanorthwindsampleapiserver.azurewebsites.net/api.rsc/"; public static final String categories = "categories"; public static final String orders = "orders"; public static final String order_details = "order_details"; public static final String products = "products"; public static final String authHeaderName = "x-cdata-authtoken"; public static final String authHeaderValue = "XXXXXXXXXXX"; public static void main(String[] args) throws Exception { OkHttpClient client = new OkHttpClient(); Response ordersResponse = client.newCall( new Request.Builder().addHeader(authHeaderName,authHeaderValue).url(url + orders).build() ).execute(); Response orderDetailsResponse = client.newCall( new Request.Builder().addHeader(authHeaderName,authHeaderValue).url(url + order_details).build() ).execute(); Gson gson = new Gson(); OrderRootObject orders = gson.fromJson(ordersResponse.body().string(), OrderRootObject.class); OrderDetailRootObject orderDetails = gson.fromJson(orderDetailsResponse.body().string(), OrderDetailRootObject.class); for (OrderDetail orderDetail : orderDetails.Value) { List<Order> order = orders.Value.stream().filter(x -> x.OrderId.equals(orderDetail.OrderId)).collect(Collectors.toList()); if(order.isEmpty()) continue; System.out.println("--------------------------------------------"); System.out.println("OrderId : " + order.get(0).OrderId); System.out.println("CustomerId : " + order.get(0).CustomerId); System.out.println("EmployeeId : " + order.get(0).EmployeeId); System.out.println("Discount : " + orderDetail.Discount); System.out.println("ProductId : " + orderDetail.ProductId); System.out.println("Quantity : " + orderDetail.Quantity); System.out.println("UnitPrice : " + orderDetail.UnitPrice); } } }
Java クライアントアプリケーションから REST API を利用するにあたってのポイント
実装は至ってシンプルにOkHttpClient を使って、Getリクエストしています。
OkHttpClient client = new OkHttpClient(); Response ordersResponse = client.newCall( new Request.Builder().addHeader(authHeaderName,authHeaderValue).url(url + orders).build() ).execute();
そして、JSONを使って、対象クラスへデシリアライズしますが、
Gson gson = new Gson(); OrderRootObject orders = gson.fromJson(ordersResponse.body().string(), OrderRootObject.class);
ちょっと面倒なのがデシリアライズ先のクラス作成です。
このくらいのカラム数ならそこまで面倒ではありませんが、ドキュメントから一つ一つ型などをチェックして、作成しなければいけません。
package com.company; import com.google.gson.annotations.SerializedName; public class Order { @SerializedName("order_id") public String OrderId; @SerializedName("customer_id") public String CustomerId; @SerializedName("employee_id") public String EmployeeId; }
JSONをベースにクラスを生成するツールなどもありますが、どこまでのJSONを対応させるのか? 動的にJSONのカラムが変わる場合などの考慮を考えると、面倒なシチュエーションも多いです。
もちろん、シンプルな REST API であれば、これで十分かなとは思いますが、これに加えてビジネスロジックも記述していくとなると、モデル部分としてはやや脆弱な部分があるのは否めないかなと思います。
また、今回は単純なリソース指定のみのリクエストでしたが、URLパラメータをどうするか、ページング処理などもどのように実装するかはドキュメントから一つ一つ読み取って実装していかないといけないのが、なかなか大変なところかと思います。
おわりに
単純に REST API を実装するだけでも、ドキュメントだけだとなかなか心許ない部分が見えてくるかなと思います。
次回はそんな部分を踏まえながら、OpenAPI(Swagger) ベースの実装を紹介します。
CData API Server で REST ful APIを作って、SwaggerHub でさくっと API ドキュメントを公開する
CData API Server では、さくっと REST Ful な Web API 開発ができるのですが、APIを生成するともれなくSwagger Spec のエンドポイントがついてきます。
そこで、ドキュメントの見やすさや Code Generate などのエコシステムが強力なSwagger(OpenAPI)を、CData API Server を使いながら、さくっとSwagger Hub で公開してみたいと思います。
SwaggerHub って?
SwaggerHub は OpenAPI(Swagger)による API 開発を行うための Spec Editor や Code Generator、Document 機能を備えたクラウドサービスです。
通常 オープンソースで提供されている一連の Swagger アプリケーションセットをサービス化したもの、言えばわかりやすいかもしれません。
そもそも Swagger って何? という方はこちらのドキュメントがわかりやすいと思います。
CData API Server の構成
CData API Server は以下のURLからトライアルの取得が可能です。
今回はAzure Web Apps上に構成して、Swagger Hubと連携できるようにしてみました。データベースは適当なサンプルDBを使って、エンドポイントを構成しています。
Azure Web Appsへのデプロイ方法は以下の記事をどうぞ。
CData API Server から Swagger Specの確認
それでは、まず構成したCData API Server から Swagger Spec を取得できるエンドポイントを確認したいと思います。
API Server の API ドキュメント画面に移動すると「/api.rsc/$swagger」というエンドポイントがあります。
このURLにをクリックすることで
以下のような Swagger Spec を取得できます。Swagger Spec は CData API Server のリソースを作成した時点で自動的に生成されます。
SwaggerHub
それでは、CData API Server の Swagger エンドポイントを使ってSwaggerHub でAPIを公開します。
SwaggerHub のプランは Free のもので大丈夫です。
SwaggerHub に移動して、左ナビゲーションから「Import and Document API」をクリック
Path or URL にCData API Server のSwagger エンドポイント URLを入力します。
おそらくログインが求められるので、CData API Server の API アクセス用ユーザーのIDとトークンを入力します。
以下の画面から入手可能です。
すると、以下のような画面に移るので、任意の名称とVersionを入力して「IMPORT OPENAPI」をクリック
以下のようにもともとJSON だったSwagger エンドポイントのデータもYAML形式に整形されて、SwaggerHubで公開されます!
もちろん、ここからClient SDKを Code Generate して使えるので、各種言語での実装が楽になりますね!
Java クライント開発におけるWeb API の実装アプローチ:その1 Web API を活用する上で意識したい APIエコシステム
最近個人的に気になったトピックとして、世界のAPI Management 市場規模のニュースがありました。
Global API Management Market Worth USD 3,436.16 Million by 2022
サイトから引用
このニュースによると、世界のAPI Management 市場は2022年までに現在の2倍(3,000億円)の市場規模になると予想されていて、「これから2倍以上もAPIが出てくるかもしれないのかぁ」と想像がつかない部分と、ワクワクした部分が同居したような感覚になったのをよく覚えています。
もちろん、API Management 系ですので、一律すべてパブリックに公開されるわけではないでしょうが、今後今まで以上にAPI を使ったマッシュアップは重要性を増すことは間違いないように思います。
しかしながら、API Management もそうですが、同じように最近よく取り上げられる「API エコシステム」についても、以下の記事にあるように提供者側を中心としたトピックではないでしょうか。
でも、APIは最終的に使うユーザー・デベロッパーが居て、はじめて真価を発揮するものですが、使う側としてこういった API の流れ、API エコシステムに対していAPIを使うデベロッパー側はどのように関わるべきか? 意識するべきか? というお話はあまり多くありません。
そこで今回 API を使う側にとっての API エコシステムをテーマに、様々な API のスタイル・プロトコルを Java のクライアント実装ベースで触りながら、それぞれの特性・エコシステムの特徴について、何回かに分けて連載をしていきたいと考えています。
今の所予定では、こんな感じです。
1. 一般的な REST API に対して HTTP Client ライブラリを利用する場合
2. Swagger(OpenAPI)Code Generateを利用する場合
3. OData ライブラリを利用する場合
4. GraphQL エンドポイントを利用する場合
5. CData JDBC Driver を利用する場合
6. まとめ
今回は初回ということで、そもそもなぜデベロッパーが API エコシステムを意識する必要があるのか?といった、このBlog記事をはじめるにあたって背景となった考えを述べていきたいなと思います。
なお、このBlogでは便宜上、API提供側をプロバイダー、API利用側をデベロッパーと書いています。
そもそもなぜデベロッパーが API エコシステムを意識する必要があるのか?
例えば、Microsoft のビジネスクラウドアプリケーション Dynamics 365(CRM)はC#とVBのSDKが公開されています。
なので認証周りや API 仕様を知らなくても、.NET 技術者は実装がしやすいのではないかなと思います。
では、Java や Python のデベロッパーは大人しくHTTP Client系ライブラリを使って実装するしか無いのか? というと、そういうわけではありません。(もちろんその実装アプローチを否定するわけではありません)
そこで一つ目を向けてほしいのが、Dynamics 365 の API は「OData」という仕様で公開されている、という点です。
以下は OData の公式サイトにあるエコシステムページです。
Ecosystem · OData - the Best Way to REST
ここに掲載されているのは、OData を提供しているプロバイダーと、ODataを使いやすくするためのサービスやツール、ライブラリの一覧です。
探してみると、これらの中に Java や Python のクライアントライブラリも書かれているのがわかるかと思います。
これらライブラリを使うだけでも、純正ではないにせよ、実装のしやすさは格段に違うものになるのではないでしょうか。
他にも、例えば電子契約サービスの クラウドサイン ではOpenAPI (Swagger Hub)でドキュメントが公開されています。
https://app.swaggerhub.com/apis/CloudSign/cloudsign-web_api/0.8.0
もちろん、これだけでも API 仕様書として見やすいことこの上ないのですが OpenAPI をベースとした Swagger Hub では Client SDK の自動生成もサポートしています。
これで Java のソースコードを生成すると、各 API Responseとなる JSON Object の デシリアライズ用 Class 生成からリクエストテストコードまで生成してくれます。
このように、API のエコシステムを知っているだけで、開発スピードに雲泥の差が出てしまうのがイメージできるのではないかと思います。
また、単純に API を REST API と表現してしまう危うさがここにあります。
REST API は「仕様」では無いため、APIの構造を元にSDKを生成したり、共通のライブラリを元に様々な Web API にアクセスできるようには提供されていません。
各プロトコルやAPI ドキュメント系特有のエコシステムが発生しづらい原因がここにあります。
なので、これから取り上げる各仕様(Swagger・OData・GraphQL)に準拠しない場合、純正のSDKを使うか、自身でHTTPベースのやり取りを実装しなければいけません。
おわりに
初回はざっくりと、全体像のお話に終始しました。
次回から実際の実装コードも踏まえながら、見ていきたいと思います。
ちなみに、今回は「gRPC」「XML-RPC」「JSON-RPC」「SOAP」などのプロトコル郡には触れないです。RPC系は社内システム間での連携の側面が強いのと、SOAPも最近めっきり聞かないですしね。
SmartHR Web API を使って、Office365 にユーザー情報を自動的に登録:RSSBus Connect
前回の記事で SmartHR Web API の基本的な機能の確認をしました。
今回は実際にありそうなユースケースベースでお伝えしたいと思います。
シナリオ
SmartHRはおそらく会社の中で一番最初にユーザーを登録する場所なので、そのデータを元に会社の各システムにユーザー情報を連携させる、というニーズが強いんじゃないかなと思います。
そこで、私も個人的に利用しているOffice365 を使って、「新入社員が SmartHRに登録されたら、Office365に新しくユーザーを作成する」というシナリオでシステムを構成してみました。
SmartHR と Office365 の接続にはRSSBus Connectというデータ連携ツールを利用します。
RSSBus Coonectとは?
RSSBus Connectは、ファイル、データベース、またはクラウドアプリケーションのデータをすべて1つのアプリケーションで簡単に統合することができるソフトウェアです。
アプリケーションとデータの接続を行い、Mrketoなどのマーケティングサービスから得た顧客情報をSalesforce等のSFAに連係したり、バイナリファイル転送・EDIによるプロセスの自動化も行うことが可能です。
RSSBus Connectは以下のようにフロー形式のUIで各データソースを繋ぐようにデータ連携のプロセスを開発することが可能です。
実行イメージ
処理内容は単純です。以下のような感じで、新しくSmartHRに新入社員が登録されたら
RSSBusConnectがバッチで起動し、SmartHR Web APIを経由して、作成された社員情報を取得。
Office365 ユーザー情報に変換し、GraphAPIを経由してユーザー情報を作成します。
以下のように登録されて完了となります!
これで、新入社員が入るたびにユーザー情報を Office365 に作成する手間が省けるかなと。
RSSBus 利用手順
それでは実際の利用手順を見ていこうと思います。
今回はすでに私が作成したRSSbusのテンプレートがあるので、それをインポートして、認証情報などを設定するだけでサクッと試すことが可能です。
必要なもの
・RSSBus Connect
・Office365 Port
・Office365 アカウント(トライアルあり)
・SmartHR アカウント(トライアルあり)
Office365 ClientIDとClientSecretの取得について
RSSBusの準備を始める前に、Office365 アカウントについて1点注意事項があります。
RSSBus Connectには標準でOffice365 GraphAPIにアクセスするためのClientIDとClientSecretが提供されていますが、セキュリティ上の考慮のため、ユーザーの作成や削除権限が付与されていません。
下記手順でAzure ADに新しくOAuth用のアプリを作成し、対象のアプリにユーザー情報を作成するための権限を付与しておいてください。
RSSBus Connect と Office365 Portのインストール
RSSBus Connect は以下のURLからトライアルを取得可能です。
製品のダウンロード後、以下のようなウィザードに従ってインストールを進めます。
そんなに難しい部分はありませんが、インストールやトライアルのアクティベーションは下記のBlogで詳しく解説しています。
Office365 Port のインストール
以下のURLからexeファイルをダウンロードして、インストールを実施します。
https://s3-ap-northeast-1.amazonaws.com/cdatajbuilds/sugimototest/SmartHR/CXTD-A_6950_free.exe
特に難しい設定はないので、そのまま次へ次へと進めればOKです。
RSSBus Connect に SmartHR Script とテンプレートのインストール
現在、RSSBus Connect の標準機能としてSmartHRの接続は提供されていないません。
なので、私が作成しましたSmartHRの接続サンプルを以下のURLからダウンロードして、使ってみてください。
テンプレートのインストール方法はこちらから。
SmartHR 接続情報の設定
それでは、実際に動かせるように RSSBus Connect の設定作業を進めていきます。
まず、SmartHR Web API を利用してJSONデータを取得している「GetSmartHRCrew」をクリックし、XMLの中の各設定値を変更します。
変更が必要なものは「TenantId」と「AccessToken」です。この部分は前回のBlogでも解説しているので、参考にしてみてください。
必要に応じて、Domainも変更します。現在はサンドボックス環境に接続するために「daruma.space」を指定しています。
ちになみにデフォルトでは、夜の11時くらいに実行して、当日作成されたユーザーを取得する想定で、 SmartHRのWeb APIをリクエストしています。
設定完了後、「Save Changes」ボタンをクリックして、設定を反映させます。
Office365 認証設定
次に「InsertOffice365User」をクリックして、設定を行います。
前述したように、RSSBus Connect には標準でClientIDとClientSecretが提供されていますが、権限が不足しているので、独自に作成したアプリのClientIDとClientSecretを
「Advanced」→「Other」の項目の中に以下のようなフォーマットで入力します。「XXXXXX」の部分をそれぞれの値に差し替えてください。
OAuthClientId=XXXXXXXXXX;OAuthClientSecret=XXXXXX;
次に「Settings」タブに移動して、接続するTenantID(hogehoge.onmicrosoft.com)を入力し、「Connect to Office365」をクリックすれば、OAuth認証が開始されます。
OAuth認証のアクセス許可が承諾されれば、設定完了です。
マッピングの変更
最後に SmartHR のデータを Office365 ユーザーとして登録する際に、どの項目をどこに当てはめるのか? といったマッピングの構成を「XMLMapCrewToUser」で行います。
「XMLMapCrewToUser」をクリックすると、SourceとDestinationそれぞれのタブがあるので、ドラッグアンドドロップなどでマッピングを変更することができます。
今回はユーザーを作成するにあたって必要最低限の以下の項目だけ設定しています。
・AccountEnabled = true を固定値で設定 ・DisplayName = SmartHR の姓・名をつないで設定 ・MailNickname = SmartHR の社員番号を設定 ・UserPrincipalName = SmartHR のEmailを設定 ・PasswordProfile_ForceChangePasswordNextSignIn = true を固定値で設定 ・PasswordProfile_Password = P@ssw0rd!を固定値で設定
以上で設定は完了です。
手動実行の方法
手動で実行する場合は一番最初のモジュールである「GetSmartHRCrew」の「Output」タブから、「Receive」ボタンをクリックすればOKです。
定期実行の構成
定期的に実行するように構成したい場合は、同じく「GetSmartHRCrew」の「Automation」タブから「Receive」を有効化して、任意の時刻設定を指定するだけです。
おわりに
今回はOffice365 と接続しましたが、他にも RSSBus Connect はADやLDAPといったDirectoryサービスや各種クラウドサービスのコネクタを提供しているので、SmartHRのデータを様々なサービスへ手軽に展開できると思います。
[接続先コネクタ一覧]
是非試してみてください。
「ZOZO 前澤社長のお年玉リツイート企画はどのくらい世の中に影響を与えたのか?」イベントを開催することになりました!
先週公開した「ZOZO 前澤社長のお年玉リツイート企画はどのくらい世の中に影響を与えたのか?500万件超えのリツイート情報の取得と分析を個人的に試みる!(仮)」記事なんですが、思いの外様々な方々から反響をいただきました!
実際にPayPalでご支援いただける方も居て、大変ありがたい限りです!
そして、Facebookでたまたま知り合いました MaP design Founder の 渡部さんご協力のもと、1月28日に日本マイクロソフト品川本社セミナールームでイベントを開催することになりました!
当日は、様々な方のご協力のおかげで実現できた500万件の取得をベースに
「Twitter APIを利用して500万件超えのリツイート情報を取得する方法」
「取得したデータから見る最新のTwitter マーケティング活用アプローチ」をお伝えする予定です!
あのリツイート騒動からなんとか1週間ほどで告知に漕ぎ着けられました。
ぜひぜひ、熱が冷めないうちにこのタイムリーなイベントに参加してみてください!
お金をもらえたはずなのに、むしろお金がかかるみたいなコンテンツに協力していただけた 渡部 さんと 日本マイクロソフトの Shohei Oda さんには大感謝です!
また、Blog公開時からご支援頂いた かがたさん、フロッグポッド小林さん、インフラジスティックス・ジャパン 東さん、エンバカデロ井之上さん、ありがとうございます!
ZOZO 前澤社長のお年玉企画リツイート企画はどのくらい世の中に影響を与えたのか? 500万件超えのリツイート情報の取得と分析を個人的に試みる!(仮)
ZOZOタウンの前澤社長が当該ツイートをリツイートしてくれた人の中から100名を対象に100万円(総額1億円)をプレゼントしてくれるという、なんとも太っ腹? な企画が動いていますね。
ZOZOTOWN新春セールが史上最速で取扱高100億円を先ほど突破!!日頃の感謝を込め、僕個人から100名様に100万円【総額1億円のお年玉】を現金でプレゼントします。応募方法は、僕をフォローいただいた上、このツイートをRTするだけ。受付は1/7まで。当選者には僕から直接DMします! #月に行くならお年玉 pic.twitter.com/cKQfPPbOI3
— Yusaku Maezawa (MZ) 前澤友作 (@yousuck2020) 2019年1月5日
Twitter上だけでなく、各メディアでも話題になっています。
申込みは1月7日12時締切になりまして、私が見たときには550万リツイートとツイッターのリツイート数世界1位になったみたいです!
私も面白い企画だなーと思って乗ってみたのですが、気になるのは対象100名の決定方法!
いろんな憶測ツイートでも出ている通り、標準のTwitterの機能だと結構制限が厳しいです。 でも、制限が厳しいとやってみたくなりますよね?
それにこんな面白そうなビッグデータ、なかなか無いのではないか?
せっかくなので、このデータを分析してみたい! どんなユーザーがリツイートしているのか知りたい! ボットはどのくらい居そう? リツイートの影響数はどのくらい? この企画の期間中にツイッターアカウントを作成した人はどのくらい?
そんないろいろと気になる疑問があったので、解決方法を探ってみました!
続きを読む