2013-11-24

force.com Web APIにおけるトランザクション処理

force.com Web APIにはREST APIとSOAP APIが存在する。

どちらもステートレスなAPI故に標準のAPIでは複雑なトランザクション処理を行うことが出来ない。

例えば、

  1. 見積オブジェクト(親オブジェクト)を作成。

  2. 1が成功した場合、1で作成した見積オブジェクトに紐づく見積明細オブジェクト(子オブジェクト)を作成。

失敗した場合は、エラー処理を行う。

  1. 2で見積明細オブジェクトを作成するのに失敗した場合は、見積オブジェクト作成前までロールバックを行う。

 

といったトランザクション処理を行う場合は標準のAPIだけでは対応できない。

 

代わりにforce.comではカスタムのREST API, SOAP APIを作成することが出来る。

このカスタムのAPIは特定Apexクラスのメソッドを呼び出すことが出来る仕組みになっており、

Apexクラス内であれば、Savepoint設置やDatabase.rollbackを行うことができるため、

上記のような要件を満たすことが出来る。

 

作成方法は簡単で

REST APIは

@RestResource(urlMapping='/TestRest/*')
global with sharing class CustomRESTController {
  @HttpPost  
  global static String customPost(){
    RestRequest req = RestContext.request;
    RestResponse res = RestContext.response;
    return 'test';
  }
}

こんな感じで書いて、

https://instance.salesforce.com/services/apexrest/TestRest/…をエンドポイントとして呼び出せばOK。

 

SOAPの方は

global class MyWebService {
    webService static Id makeContact(String lastName, Account a) {
        Contact c = new Contact(lastName = 'Weissman', AccountId = a.Id);
        insert c;
        return c.id;
    }
}

こんな感じで書いたクラスのWSDLをエクスポートして、

利用する言語ごとにSOAP APIを使ってあげれば良い。

 

一応、両方可能ではあるが、SOAP APIの方は

JavaとかC#みたいに比較的使いやすいSOAPクライアントがあれば良いけど、

phpとかだとやや厳しいし、定義を変更するたびにWSDLをダウンロードする手間があるので、

個人的にはREST APIの方を推奨。

 

ただしREST APIだと複数件レコードに対する一括処理をするには

カスタムREST APIを使うしかないので、そこの部分で調整は必要。

 

また、前述のとおり、カスタムのAPIはApexクラスのメソッド呼び出しなので、

・既存のApexクラスの使い回しが可能

・外部アプリの操作をApexクラスで一元管理できる

というメリットがあるものの「ガバナ制限」が付きまとってしまうので、

その部分も考慮しないとダメ。

 

一日あたりのAPI最大値の制限内であれば、

Apexクラスではダメになっちゃうようなバッチ処理でも

API経由であれば可能になるところは、API利用の一つの利点だと思っているので、

上記の点は設計する上で注意っす。

このエントリーをはてなブックマークに追加