Java クライント開発における Web API の実装アプローチ:その4 OData 編
前回は API 記述言語ベースの Swagger でお送りしましたが
今回はレイヤーを変えて、Web API のプロトコルとして提供されている OData で紹介していきます。
最初の記事はこちらから。
OData って何?
ODataは、データモデルの記述、およびそれらのモデルに従ったデータの編集および照会をサポートするプロトコル。 ざっくり言ってしまうと、表形式データの“編集”および“照会”を強みとしたREST ful なプロトコルです。
特徴指定は、以下のような点があげられます。
・ メタデータ:特定のデータプロバイダによって公開されるデータモデルの機械可読の記述。
・ データ:データエンティティのセットとそれらの間の関係。
・ クエリー:サービスがフィルタリングとデータへの変換を実行するよう要求し、結果を返す。
・ 編集:データの作成、更新、および削除。
・ 操作:カスタムロジックの呼び出し
・ボキャブラリ:カスタムセマンティクスの付加
引用元:OData Web Services
http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html
個人的に特にとりあげるべきと考えるポイントは、REST API における URIに のフォーマットを統一したことにあるでしょう。
$top、$select、$filterといった、ある種SQLライクにWeb APIのデータリクエストを定型化することで、表形式データの取得アプローチを最適化しています。
また、EDMと呼ばれるMetadataエンドポイントを備えているので、各種フィールドや型を確認できるのも強みですね。
ODataで公開されているサービス
もともとMicrosoft が始めたためか、どちらかと言えばエンタープライズ寄りなサービスで提供されています。
・Dynamics 365 Wev API
・Office365 GraphAPI
などなど。
国内ですと、三菱UFJ国際投信が投信情報 API を OData で提供していたりします。
OData エコシステムのポイント
OData は統一されたURIのクエリアプローチとメタデータ提供により、BI系やETL系などのツール、サービスなどによるエコシステムが強力です。
例えばMicrosoft PowerBIから接続できるコンポーネントがあったり
Azure DataFactory にデータソースとしての接続先があったりします。
もともと Microsoft が提唱したプロトコルのため、Microsoft エコシステムでのサポートは強力ですね。
Java で Odata を使うためのライブラリ
Java で 一番のメジャーどころかつ、クライアントサイドもサポートしているライブラリとして「Apache Olingo」があります。今回はこれを利用して OData API に対する Java クライアントを構成します。
参考:OlingoによるOData v4サービスのデータへのアクセス
Accessing data of OData v4 services with Olingotemplth.wordpress.com
対象の API
対象の API は前回と一緒です。SwaggerHub で公開していますが、ClientSDKなどは使用せず、OData プロトコルの特性をいかして実装します。
https://app.swaggerhub.com/apis/sugimomoto/CDataNorthWindSample/1.0.0
操作も同じように注文データ(orders)と注文明細データ(order_details)を取得して結合したものをコンソールで出力するというものです。
実装コード
Java クライアントアプリケーションから OData を利用するにあたってのポイント
ポイントはODataの特徴でも解説した通り、リクエストを実行する際のURI作成アプローチにあります。
Olingo では URIBuilderというクラスで対象のリソースの指定(ordersやorder_details)、取得件数の制御($top=10)、keyとなるidの指定を実施できるメソッドを備えています。
URIBuilder uri = client.newURIBuilder(serviceRoot).appendEntitySetSegment(entityName).top(10); if(id != null) uri.id(id);
それ以外にもfilterやselectなど、基本的なOData のリクエスト URI を構成するためのメソッドが備えられているため、いちいち API のドキュメントを確認しながら、URIの構成を考える必要がありません。
また、コンソールにレコード、カラムの値を出す際にも、Swagger や REST APIの場合、以下のようにハードコードしていた部分を
System.out.println("--------------------------------------------"); System.out.println("OrderId : " + order.get(0).getOrderId()); System.out.println("CustomerId : " + order.get(0).getCustomerId()); System.out.println("EmployeeId : " + order.get(0).getEmployeeId()); System.out.println("Discount : " + orderDetail.getDiscount()); System.out.println("ProductId : " + orderDetail.getProductId()); System.out.println("Quantity : " + orderDetail.getQuantity()); System.out.println("UnitPrice : " + orderDetail.getDiscount());
メタデータの取得ができるため、以下のようなカラムを全部持ってきて、繰り返し出力するような記述を行うことが可能です。
orderDetail.getProperties().forEach(x -> System.out.println(x.getName() + " : " + x.getValue() ));
(一応、Olingo のプラグインを使って、事前にモデルとなる Class を生成することも可能みたいです。個人的には .NET Visual Studio で実装するほうが楽だったり)
動的にカラムが可変するようなアプリケーションを実装する場合は特に楽になるのではないでしょうか。
おわりに
個人的にも愛着がある OData でお送りしましたが、サーバーサイドの実装が重いこともあり、最近は下火になりつつあるかなという感じは否めません。
ただ、上記でも紹介した通り、Microsoft系、エンタープライズ系では結構使われているので、OData という認識があるだけでも、実装しやすくなるシチュエーションはまだまだあるのではないかと思います。