Apex似のSOQL呼び出しJavaコーディングの実験

October 27, 2016 Toshiki Iga

こんにちは、いがぴょんことアピリオの伊賀敏樹です。

外部JavaアプリケーションからSalesforce/Force.comを呼び出すインタフェース・プログラミングについて、SOQL に着眼してコーディングをApex似に実装する実験を趣味的に試みてみました。多少の工夫によって近似したコーディングは実現できましたので、ご参考までに紹介します。

着眼点

SOQL と DML

今回着眼したのはSalesforce Object Query Language (SOQL)とDMLについてです。SOQLはForce.com上で利用可能なSQLに似たForce.com専用のオブジェクト問い合わせ言語です。外部アプリケーションからForce.comの呼び出しは、SOQLおよびDMLの呼び出しによるデータ取得・データ操作であることが一般的に主流であるため、SOQLおよびDMLに着眼しました。

Java と SOAP / WSDL

これを呼び出すプログラミング言語としてJava言語を選択しました。ApexはForce.com上で利用可能なプログラミング言語ですが、ApexはJava言語に似た言語仕様を採用しています。ですので、多少のラッパーを用意したら、Apex似のJavaコーディングが可能であるとの着眼です。

そして、Force.comとJavaとの間の通信方式にはSOAP/WSDLを選択しました。これはApex、Javaともに「強い型付け」言語である特徴を持ち、Force.comと呼び出し側Javaとが「強い型付け」で結びつけられるのがポイントです。このため、ここではEnterprise WSDLを利用してJavaクライアント側インタフェースを生成したことを前提に話を進めます。ちなみに、Enterprise WSDLからのクライアント側インタフェース生成についてはこちらを参照してください。

なお、現実的なForce.com開発において、ある程度の処理を記述する場合にはSOQLリモート呼び出しによる業務実装よりも、Apexオブジェクト側に置いてSOQL呼び出しを伴った業務実装を行い、このApexオブジェクトに対してHTTP(S)/RESTリモート呼び出しする方式のほうが主流です。これを選択する理由としては、性能面の大きな有利性や業務トランザクションの一貫性実現など様々なことがらが挙げられると考えられます。

ラッパー・ライブラリ

Java側のApex似のラッパー・ライブラリについてですが、Enterpirse WSDLから生成される機能ですでにApexと相似したAPIが提供されてるため、あとはSystem.DatabaseやSystem.QueryExceptionなどに着眼して主要なラッパー・ライブラリを作ってみました。なお、ApexのSystemやSystem.ExceptionについてはJava標準ライブラリと名前が衝突してしまうため、止むを得ずApexSystemのように「Apex」プレフィクスを付与するように対応しました。

実現できること

これらの取り組みにより、Java側でForce.com上の各種オブジェクトに対してSOQLおよびDMLについて、以下のようなApex似の実装が実現できます。なお、完全なソースコードについてはSimpleSampleCls.javaを参照してください。

SOQL

Database.queryの形式によるSOQL呼び出しが実現できました。SOQLの記述、SObjectによる取り出しアクセス、そしてそれをForce.com上の取引先(Account)オブジェクトへのキャストおよびアクセスが可能になります。例外もQueryExceptionでキャッチできるようになっている点も、相似を実現するために重要なポイントです。また、ここでは示しませんが、LIMIT 1を用いた1レコード取得や集計関数を利用したアグリゲーション結果取得も可能です。

try {
	List<SObject> sObjList = Database.query(conn,
		"select Id, AccountNumber, BillingAddress, BillingGeocodeAccuracy" //
		+ ", CreatedById, CreatedDate, Description, Fax, Phone" //
		+ "    from Account");

	for (SObject sObj : sObjList) {
		Account lookup = (Account) sObj;
		ApexSystem.debug("id: " + lookup.getId());
		ApexSystem.debug("  desc: " + lookup.getDescription());
		ApexSystem.debug("  fax : " + lookup.getFax());
		ApexSystem.debug("  tel : " + lookup.getPhone());
	}
} catch (QueryException ex) {
	ApexSystem.debug("exception occured. reason : " + ex.toString());
}

DML

Database.insert、Database.update、Database.upsert、Database.deleteの形式によるDML実行が実現できました。この例ではForce.com上の取引先責任者(Contact)オブジェクトのインスタンスを作成および値を設定した上で、Database.insertを呼び出すことによりForce.com上にレコードを追加することを実現しています。レコード追加に成功した場合にはid項目に値がセットされます(生成されたAPIだけだとApex同様の自動セットは実施されない点に注意)。ここでは示しませんが、Listによる複数件の一括処理も可能でした。

try {
	Contact contact = new Contact();
	contact.setLastName("TestUserForBlancoApexUtil");
	contact.setFirstName("Test");
	contact.setEmail("uso@example.com");

	SaveResult sr = Database.insert(conn, contact);
	if (sr.isSuccess() == false) {
		System.out.println("FAIL");
	}
} catch (DmlException ex) {
	ApexSystem.debug("exception occured. reason : " + ex.toString());
}

おわりに

ここで紹介したように、工夫によって外部JavaアプリケーションからSalesforce/Force.comを呼び出すインタフェース・プログラミングのコーディングをApex似に真似させることは可能であろうことがわかりました。ここで示した互換ラッパー・ライブラリによって Java 側の Force.com呼び出しはApexにとても似たものにできることが実験できました。ちょっとした工夫でApexそっくり Javaによるリモート呼び出しができたという、趣味プログラミングの紹介でした。

戻る
Lightning Experience再入門(1)
Lightning Experience再入門(1)

こんにちはアピリオ北嵐です。時が経つのは早いものでWinter'16でデビューしたLightning Experience(以降LEXと記述)もこの秋で1周年を迎えました。リリース直後は若干不安定で機能的にも少し物...

次へ
Apexを使用してSpringCMからチャンク内の大きなドキュメントにアクセスする方法
Apexを使用してSpringCMからチャンク内の大きなドキュメントにアクセスする方法

2016年8月12日 by Satyanarayan Choudhary  本ブログはアピリオUSのテックブログにSatyanarayan Choudharyが寄稿した記事を抄訳したものです。 原文 ”How to...

アピリオまでお気軽にお問合せください

ご質問はこちら