2月20日(水)に虎ノ門で「Windows女子部/初心者向け:Dynamics365 カスタマーサポート業務での活用ポイント解説」を開催します!
Burikaigi 2019に続いて、Dynamics 365 関係で登壇することになりました。
今回はMS MVP の方々がリレー形式で登壇を担当する企画を開催している「Windows女子部」で発表します。
そして、珍しくというか、久しぶりにというか、初心者向けと銘打って、カスタマーサポート機能を中心に「Dynamics 365 Customer Engagement」を解説する予定です。
具体的にどんなお話をするの?
でも、そもそも今回お話する「Customer Engagement」、名前からして、今までDynamics 365 に関わってこなかった方々にはよくわかんないですよね。
顧客管理とかSFAとかMAとか、キーワードや世の中の風潮?みたいなもので大事っぽいっていうのはなんとなく理解している。
でも、じゃあ Dynamics 365 を使ったからって何が変わるの? っていうのがイメージできない。そんな方が多いのではないかなーと漠然と思ってます。
今回実は初心者向けとは銘を打ちつつも、個人的に結構新しい試みをしていて、昨今のビジネスモデルを土台にしながら、Dynamics 365 をどのように解釈すればいいのか? その上で、なんでこんな機能があるのか? どんな風に使えるのか? というのをお話する予定です。
是非、今まで Dynamics 365 を触ったことが無い人も、触っている人も、開発している人も、参加してもらいたいなーと思います。
3月1日(金)に仙台で「【JAZUG TOHOKU】ZOZO前澤社長お年玉リツイート企画のビッグデータに立ち向かう方法」を開催します!
1月28日(月)に日本マイクロソフト品川本社セミナールームで開催した「ZOZO 前澤社長のお年玉リツイート企画は、どのくらい世の中に影響を与えたのか?」の仙台スピンオフを開催することになりました!
イベントページはこちらからどうぞ。
【JAZUG TOHOKU】ZOZO前澤社長お年玉リツイート企画のビッグデータに立ち向かう方法 - connpass
東京開催時のTwitterまとめもあるので、どんな感じなのかなーと気になっている方は見てみてください。
会場は以前も Azure 勉強会でお世話になりましたSRIAさんのオフィスです! 仙台駅から徒歩圏内。
セッション終了後には LT & ビアバッシュ会になっていますので、是非お気軽にご参加ください!
500万件を超えるTwitter のリツイート データを取得・分析する方法 -Twitter Premium Search API を実際に使ってみてわかった嵌りポイントとその対策-
このBlogでも告知していましたが、今週の月曜日1月28日に日本マイクロソフト品川本社セミナールームC+D で「ZOZO 前澤社長のお年玉リツイート企画は、どのくらい世の中に影響を与えたのか?」を開催しました!
開催前はこんな色物企画に本当に人が来てくれるのだろうか? とずっと半信半疑でしたが、最終的に申込みは4営業日ほどで満席(108席)になりまして、イベント当日もたくさんのツイート、ご質問をいただけて、個人的にとても得るものも多く、楽しいイベントとなりました!
以下のまとめでどんな雰囲気だったか垣間見ることができるのではないかなと思います。
ただ、私自身がやったことは、このイベントのタイトルから見えるよりも、ひたすら地味なもので、Twitter API の「制約」・「制限」・「仕様」をどのように回避・咀嚼しながら、対象の500万リツイートデータ取得と分析に挑むのか? といったものでした。
もちろん、取得してきたデータから見えてきたことも最後のほうで紹介したいと思いますが、この記事としては今後 Twitter 上でキャンペーンなどを展開していく企業やユーザーの役に立ってもらえればという考えで書いています。
こんな色物な取り組みですが、是非いろいろと参考にしてもらえると幸いです。
なお、さっくりと見たい方にはほぼ同じ内容のスライドも公開しています。
- なんでこんなことをしようと思ったのか?
- 立ちはだかる「嵌りどころ・落とし穴」たち
- 1.どうやって500万件のリツイート(+アルファ)を取得するの?
- 仮に ZOZO前澤社長が本気で API を使って抽選しようとした場合どうなるか?
- 2.どうやって対象のツイートを識別するの?
- ボトルネック③ どうやって Twitter の JSON データを構造化するの?
- Basic Tweet Format
- Extended Tweets Format
- Retweets Format
- Retweets and Quote Tweets Format
- 解決アプローチ
- ボトルネック④ どうやって DB にデータを流し込むの?
- めんどくさいこと
- データ投入アプローチ
- 終わりに
Java クライント開発における Web API の実装アプローチ まとめ REST vs GraphQL vs Swagger vs OData
最近作成してきた、Java クライント開発における Web API の実装アプローチのまとめ記事です。
初めての試みでしたが、私自身多くの発見があり、とてもいいナレッジになったのではないかなと思っています!
この記事では、まとめとして総括した内容を中心にお伝えしますが、是非以下の記事郡を見てほしいと思います。
タイトルでは vs なんてことを書いていますが、それぞれの特徴を把握してもらうことを目的としています。
各記事の一覧
Java クライント開発におけるWeb API の実装アプローチ:その1 Web API を活用する上で意識したい APIエコシステム - Morning Girl
Java クライント開発における Web API の実装アプローチ:その2 一般的なREST API編 - Morning Girl
Java クライント開発における Web API の実装アプローチ:その3 Swagger(OpenAPI)Code Generate 編 - Morning Girl
Java クライント開発における Web API の実装アプローチ:その4 OData 編 - Morning Girl
Java クライント開発における Web API の実装アプローチ:その5 GraphQL 編 - Morning Girl
Java クライント開発における Web API の実装アプローチ:その6 CData Driver編 - Morning Girl
REST・Swagger・OData・GraphQL比較表
あまりマルバツ表は好きではないのですが、改めてそれぞれの特徴をまとめました。
REST を比較するのはあまりにも難儀ですが、ここからも「結局の所 REST はデザインパターンである」ということが明確にわかるのではないかなと思います。
あまり意図してつけたわけではないのですが、思ったよりもそれぞれの長所・短所がはっきりする結果になったのではないかなと思います。
Swagger・OData・GraphQL それぞれを使ってみた所感
Swagger
Code Generate で生成した Client SDKの使いやすさはピカイチでした。現在公開されている API を右肩あがりですので、知っておいて損は無い仕様だと思います。
ただ、ドキュメントのアップデートに気を使っているかどうかは、そのプロバイダーにかかっていますし、メタデータは Swager の記述アプローチ次第なところもあるので、その辺を注意しながら使う必要はあると思います。
OData
スキーマやリクエストのコントロールのアプローチは確立されていますが、アーキテクチャとしての複雑さ、使う敷居の高さは若干否めません。
ただ、Salesforce・Dynamics 365・SAP などが OData で API を提供しているため、エンタープライズ領域としては把握しておいて損は無いでしょう。
特に、ツールやサービスとの接続には依然多く利用されるシチュエーションに溢れているため、この点を知っているかどうかで、選択肢の幅は大きく変わります。
GraphQL
上でも述べた通り、Java Client から使う、となるとまだまだ敷居の高さは否めません。
実際のところ Java で使うよりも、React といった Java Script系クライアントライブラリで利用する、というシチュエーションの方が、現在は多いと思います。
しかしながら、Github や Shopify がパブリックなAPIを公開したところを見るに、これからエンタープライズ領域でも見かけるシチュエーションは多くなるのではないでしょうか。
Microsoft も一部ベータ的に GraphQL API を公開し始めましたし、今後ウォッチしておく価値はあると思います。
最後に。なぜ開発者が API のエコシステムを理解しておくことが大事なのか?
おそらく Swagger と GraphQL が出てきたタイミングから Web API(REST)の捉え方は変わってきています。
ただ Web API(ないしREST)として、それらに接することはあまりにも脆弱になってしまったのだと思います。
Swagger で CodeGenerate することを知らなければ、クラス名を一から記述することになり
OData で Metadata を取得することを知らなければ、動的なアプリケーションは作りづらい
仕様であることを理解しているだけで、開発者が取れる選択肢は格段に多くなります。
そして、それが適切かつ保守しやすい開発に繋がることは間違いないでしょう。
API を実装する側ではないからといって、API エコシステムを疎かにしてはいいわけではない理由がここにあると思います。
是非、各仕様・エコシステムを理解してもらいながら、開発に役立ててもらえたらなと思います。
Java クライント開発における Web API の実装アプローチ:その6 CData Driver編
前回まで 主に各API規格の仕様ベースでアクセスする方法を紹介してきました。
今回はちょっと趣向を変えて、JDBC、つまりデータベースを操作するSQLベースで Web API にアクセスする方法を提供している CData JDBC Driver を紹介します。
最初の記事はこちらから。
CData JDBC Driver って何?
Facebook や Twitter 、Dynamics 365 や Salesforce といった 100 を超える クラウドサービス・Web API・NoSQL に JDBC で接続を可能にするという Driver・ライブラリ製品です。
例えば今まで紹介してきた以下の API の注文(orders)テーブルに CData JDBC Driver でアクセスする場合は
https://app.swaggerhub.com/apis/sugimomoto/CDataNorthWindSample/1.0.0
「SELECT * FROM orders」といったSQLの形式で実行するだけで実現可能になります。
CData Driver 内部では リクエストされたSQL を分解し、Web API の HTTP Request に組み立て直し、レスポンスの JSON をレコードセット形式にフォーマット化、クライアントに返すという仕組みです。
実際にCData Driver のログを確認してみると、以下のように SELECT 文が発行された後、HTTP Requestが実行されていることがわかるかと思います。(ログデータは若干省略しています。)
[Connection: 8] Executing query: [SELECT [orders].[order_id], [orders].[order_date],[orders].[customer_id],[orders].[employee_id],FROM [orders]LIMIT 100]. [Connection: 8] [Request] GET https://cdatanorthwindsampleapiserver.azurewebsites.net/api.rsc/orders?$select=order_id%2Corder_date%2Ccustomer_id%2Cemployee_id&$top=100 User Authorized SSL Cert: [TRUSTED] Server Cert: [LS0tLS1CRUdK] Accepted: True [Connection: 8] [Response] HTTP/1.1 200 OK, 1844 Bytes Transferred [HTTP Headers] HTTP Auth Scheme: 3 GET /api.rsc/orders?$select=order_id%2Corder_date%2Ccustomer_id%2Cemployee_id&$top=100 HTTP/1.1 Host: cdatanorthwindsampleapiserver.azurewebsites.net Accept-Encoding: gzip, deflate User-Agent: CData Data Provider Engine - www.cdata.com - Accepts: gzip OData-MaxVersion: 4.0 accept: application/json;odata.metadata=full x-cdata-authtoken: 1q0E5n7v8V1k4r1U5g0e [Connection: 8] [Response] [HTTP Headers] HTTP/1.1 200 OK Cache-Control: private Transfer-Encoding: chunked Content-Type: application/json;charset=utf-8 Content-Encoding: gzip Vary: Accept-Encoding Server: Microsoft-IIS/10.0 X-Powered-By: CData API Server OData-Version: 4.0; X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Wed, 23 Jan 2019 05:34:37 GMT {"@odata.context":"hello$metadata#orders","value":[{"order_id": 10248, "employee_id": 5, "order_date": "1996-07-04", "customer_id": "VINET"}]} [Connection: 8] Page successful: 100 results (1,525 ms).
対象の API
対象の API は今までと一緒です。
https://app.swaggerhub.com/apis/sugimomoto/CDataNorthWindSample/1.0.0
同じようにODataベースの REST API なので、CData JDBC OData Driver を使ってアクセスします。以下からトライアルのダウンロードが可能です。インストール後、Javaプロジェクトでライブラリを参照してください。
https://www.cdata.com/jp/drivers/odata/jdbc/
操作も同じように注文データ(orders)と注文明細データ(order_details)を取得して結合したものをコンソールで出力するというものです。
実装コード
APIに接続する場合の接続文字列は CData OData JDBC Driver 独自のものになります。URIでAPIのエンドポイントを指定し、認証部分記述すればOKです。
jdbc:odata:URL=https://cdatanorthwindsampleapiserver.azurewebsites.net/api.rsc;Custom Headers=x-cdata-authtoken:XXXXXXXXX;
実際にOrdersテーブルのとOrderDetailsテーブルにアクセスしたソースコードはこちら。
Java クライアントアプリケーションから CData Driver を使うポイント
まずはなんといってもSQLでアクセスできることでしょう。
HTTP動詞やWeb APIのエンドポイントURLなどを意識することなく、データの取得操作が実施できます。
String sql = "SELECT [orders].[order_id], [orders].[order_date],[orders].[customer_id],[orders].[employee_id],[order_details].[discount],[order_details].[product_id],[order_details].[quantity],[order_details].[unit_price]FROM [order_details] LEFT OUTER JOIN [orders] ON [order_details].[order_id] = [orders].[order_id] LIMIT 100;"; Statement stat = conn.createStatement(); boolean ret = stat.execute(sql);
それに加え、ただSELECTするだけではなく、JOINやWhereなど、SQLの規格に則った記述ができるので、各エンドポイントからデータを取得して、それをクライアントサイドでマージするといった処理を書く必要がありません。
また JDBC 規格で提供しているので、スキーマ・メタデータ情報にもアクセスすることができます。
以下の処理は取得したデータのMetadataからカラム名を特定し、それぞれのカラム名とカラムバリューを取得している行です。
for(int i=1;i<=rs.getMetaData().getColumnCount();i++) { System.out.println(rs.getMetaData().getColumnName(i) +" : "+rs.getString(i)); }
終わりに
今回は Java クライアントアプリケーションから接続した例で紹介しましたが、JDBC接続をサポートしているアプリケーションやサービスからも内部に組み込むだけで、アクセス先をDBではなくWeb APIに切り替えるということが可能です。
前回までは各仕様のインターナルな部分におけるエコシステムを中心とした紹介でしたが、こういった外部でも育まれているエコシステムを活用することも一つの選択肢だと思います。
次回は今までの投稿内容をふくめて、まとめに入りたいと思います。(長かった・・・)
Java クライント開発における Web API の実装アプローチ:その5 GraphQL 編
前回は REST ful な API プロトコルの OData でJavaクライアントを実装してみました。
今回は、2015年に公開された割と新しいAPI プロトコルであるGraphQLで実施してみたいと思います。
GraphQL は数年前に比べると海外のカンファレンスも活発に開かれるようになり、エコシステムも充実の兆しを見せています。
最初の記事はこちらから。
GraphQL とは何か?
GraphQL は 2015年 に Facebook が公開した Web APIのための新しいクエリ言語です。
独自の構造的なクエリ言語を用いることで、一つのエンドポイントで複数のリソース、ネストされた構造体のデータを取得することがしやすいように構成されています。
私が手っ取り早く、GraphQLという思想の理解を促そうとするならば、Facebookの画面を見るのが早いと思っています。
FacebookのWeb siteにアクセスすると、以下のような画面が表示されるかと思いますが
これらのデータは、私を中心として、友達や所属しているグループ、私のタイムラインなど、様々なリソースから取得したデータを元に構成されています。
これが、今までのRESTの思想で実装する場合、以下のようにリソースごとのリクエストを都度実施する必要がありました。(まあ、一つのエンドポイントで全部返すってこともREST思想的にはできますけど)
それをGraphQLであれば、以下のように一つのリクエストで関係性を持つデータを一括で取得して、クライアントサイドへレンダリングするということが実現することができます。
このように、REST の思想によるボトルネックを解消しようとして開発されたのが、GraphQL です。
なお、リソースの作成などで使う Mutation や アップデートなどの通知を受け取るための Subscription といった仕組みもありますが、今回は割愛します。
GaphQLで公開されているサービス
現状はどちらかと言えば、インターナルなAPIとして。React等の組み合わせた利用シチュエーションが多いと言えますが、Github や Shopify などがオープンなAPIとしても提供を進めています。
・Github https://developer.github.com/v4/
・Shopify https://help.shopify.com/en/api/custom-storefronts/storefront-api
あと、とっつきやすいプロジェクトとして、StarWarsデータを扱ったGraphQL APIがあります。
こちらは認証無しで触れるので、試しに GraphQL を触って見るにはもってこいだと思います。
対象の GraphQL 環境
対象となるGraphQLの環境は Hasura というオープンソースのGraphQL Server アプリケーションで作成しました。
PostgreSQL の既存DBからGraphQL APIを自動生成してくれたり、GraphQLスキーマからDBを生成してくれたりするすぐれものです。
データ構成は、REST や Swagger の記事で公開したものと一緒ですので、シナリオも変わりません。環境の構築方法はまた別の記事にまとめたいと思います。
そして、作成したGraphQL環境はこんな感じです。
たとえば、以下のようなQueryをリクエストすると
query{ orders{ order_id customer_id employee_id order_details{ product_id quantity discount } } }
こんな感じのレスポンスが返ってきます。
{ "data": { "orders": [ { "order_id": 10248, "customer_id": "VINET", "employee_id": 5, "order_details": [ { "product_id": 11, "quantity": 12, "discount": 0 }, { "product_id": 42, "quantity": 10, "discount": 0 }, { "product_id": 72, "quantity": 5, "discount": 0 } ] }, { "order_id": 10249, "customer_id": "TOMSP", "employee_id": 6, "order_details": [ { "product_id": 14, "quantity": 9, "discount": 0
ちなみに、HTTPでリクエストする場合は、以下のような形式になります。
POST /v1alpha1/graphql HTTP/1.1 Host: sampledbforjavawebapi.herokuapp.com {"query": "{orders{order_id,order_date,customer_id,employee_id,order_details{product_id,unit_price,quantity,discount}}}"}
Java クライアントアプリケーションから快適にGraphQLを使う方法
GraphQL API も 言ってしまえば、クエリをPOSTで投げて、JSONを返す API ですので、HTTPクライアントと JSON パーサーを使えば実装できないこともありません。
でも、それだとあまりにも、GraphQLを恩恵を受けられないので、GraphQL API を公開している Shopify が開発しているJava用 GraphQLコードを生成するプログラムを利用して、試してみたいと思います。
これを利用することで、ラムダベースでGraphQL Queryが作成できたり
String queryString = ExampleSchema.query(query -> query .user(user -> user .firstName() .lastName() ) ).toString();
GraphQLスキーマをベースに生成したデシリアライズ用クラスへインプットできたりします。
ExampleSchema.QueryResponse response = ExampleSchema.QueryResponse.fromJson(responseJson); ExampleSchema.User user = response.getData().getUser(); System.out.println("user.firstName() + " " + user.lastName());
GraphQLはその性質上、ネストされた構造体を扱いやすいので、かなり恩恵を受けやすいと思います。
GraphQLJavaGenを使う手順 必要なもの
最終的にはもちろんJavaなんですが、それまでの過程でNode.jsとRubyが必要になります。
ただ、基本的にはコマンドを叩くだけなので、そこまで難しくは無いです。それぞれの言語とパッケージ管理ツールをインストールしておきましょう。
・node.js https://nodejs.org/ja/
・ruby https://www.ruby-lang.org/ja/
・bundler https://bundler.io/
GraphQLJavaGenを使う手順① GraohQL スキーマ JSON形式の生成
まず、対象のGraphQL API から スキーマのJSONファイルを生成します。
node.js環境とnpmが必要になるので、あらかじめインストールしておきましょう。
手順はそんなに難しくありません。まずGraphQL をコマンドから実行できるようにする「graphqurl」をnpmでインストールして
npm install -g graphqurl
以下のようなコマンドで対象のGraphQL API を指定すれば、カレントフォルダにスキーマファイル(JSON形式)が生成されます。
gq https://sampledbforjavawebapi.herokuapp.com/v1alpha1/graphql --introspect --format json > schema.json
ただ、なぜか生成したスキーマファイルは、後ほど実施するCode Cenerator 用として、ルートObjectに「data」が無いので、それを追加しておきます。
あと、現在「smallint」型が対応していないので、Intに置換しました。
GraphQLJavaGenを使う手順② Java ClientSide Code Generator for GraphQL
それでは、実際に GraphQLJavaGen を使ってJavaのソースコードを生成したいと思います。
あらかじめruby と bundlerが必要となるので、インストールしておきます。
ダウンロードした GraphQL スキーマも配置されているフォルダで bundler をinitializeし
bundler init
生成されたGemfileに以下の gem を追加
gem 'graphql_java_gen'
対象ファイルに Ruby ファイル(.rb)を作成して、読み取るファイル、アウトプットするファイル名を指定すればOKです。
require 'graphql_java_gen' require 'graphql_schema' require 'json' introspection_result = File.read("schema.json") schema = GraphQLSchema.new(JSON.parse(introspection_result)) GraphQLJavaGen.new(schema, package_name: "com.company", nest_under: 'GraphQLSchema', custom_scalars: [ GraphQLJavaGen::Scalar.new( type_name: 'Decimal', java_type: 'BigDecimal', deserialize_expr: ->(expr) { "new BigDecimal(jsonAsString(#{expr}, key))" }, imports: ['java.math.BigDecimal'], ), ] ).save("#{Dir.pwd}/GraphQLSchema.java")
実行すると、以下のような Java のソースコードが生成されます。
実装コード
それでは、実際に生成されたソースコードを使って実装してみたいと思います。
必要なライブラリは以下のとおりです。
・OkHttpClient
・GSON
・com.shopify.graphql.support:support:0.2.0
Java クライアントアプリケーションから GraphQL を利用するにあたってのポイント
ライブラリ紹介のところでもすでに伝えていますが、なんといっても Query を Java のラムダで書くことができるのが素晴らしいです。
String graphqlRequest = GraphQLSchema.query(query -> query.orders( orders -> orders .orderId() .orderDate() .customerId() .employeeId() .orderDetails(orderDetails -> orderDetails .productId() .unitPrice() .quantity() .discount() ) )).toString();
ちなみにgraphqlRequest の中身はこんな感じになります。
{orders{order_id,order_date,customer_id,employee_id,order_details{product_id,unit_price,quantity,discount}}}
1:Nで構成されている Order と OrderDetails の関係性もラムダで表現でき、かつGraphQLを書いた場合と変わらずに直感的に記述できるのがいいですね。
この Query を用いて、素直にHTTP POST リクエストでGraphQLサーバーに渡します。
受け取った JSON は「QueryResponse.fromJson.getData().getXXXXXXX()」で各データ格納クラスにList<> で展開することができます。
GraphQLSchema.QueryResponse queryResponse = GraphQLSchema.QueryResponse.fromJson(response.body().string()); List<GraphQLSchema.orders> orderList = queryResponse.getData().getOrders();
このように、GraphQL でリクエストを投げるところから、レスポンスを受け取るところまで、GraphQLの特性を活かしながら実装することができるので、あまりGraphQLだからといって敷居を高く感じることなく、Javaで操作できるのではないでしょうか。
(ただ、生成はちょっと大変・・・。)
おわりに
今まで私自身 node.js でしか GraphQL を触っていなかったのですが、静的型付の Java でもこんな感じで操作できることがわかると、バッチなどの実装しやすさは相当変わるなぁと感じました。
もうちょっと Java のエコシステムにも GraphQL カルチャーが浸透してほしいところではありますが、 GraphQL自体もこれから発展していく様相のプロトコルですので是非今後に期待したいなと思います。
それでは、次回は若干番外編として CData Driver で Web API を叩く方法を紹介したいと思います。