こんにちは。CData Software Japanリードエンジニアの杉本です。
以前このBlogでSalesforce のAPI Limitについて解説したことがありました。
www.cdatablog.jp
この記事の中で、この合計API要求数要求の割当および消費状況の確認方法は、Salesforce の「設定」→「システムの概要」にある「API 使用状況」で見れるよ-、と記載していたのですが

プログラムやCData Driver を使っている過程でAPI Limitを監視したい、確認したいという要望もあるかと思います。
実は最近そのAPI Limit状況を確認するための新しい機能が追加されたので、今回の記事ではその新機能を紹介したいと思います。
GetLimitInfo ストアドプロシージャについて
新しく追加された機能は「GetLimitInfo」というストアドプロシージャです。
cdn.cdata.com
ODBC、JDBC、ADO.NET など全ドライバー共通の機能です。
www.cdata.com
使い方はとても簡単で以下のようにSQLでストアドプロシージャを実行するだけです。
Exec GetLimitInfo;
実行すると以下のように現在のAPI Limit消費状況「Current」と、API Limitの「Limit」が表示されます。

これでプログラムからもAPI limitの消費状況を確認し、プログラムやツールでのハンドリングが可能になります。
「GetLimitInfo」 はどうやってAPI Limitを表示しているの? 内部のアルゴリズムについて
ここからは少し内部のお話を。
そもそも、このAPI Limitなんですが、CData Driver関係なく、通常のSalesforce APIではどうやって確認するかといえば、API リクエスト実行時のレスポンスBodyに入っている値になります。
例えば、SOAP APIを使って以下のようなSOQLをリクエストすると
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns="urn:enterprise.soap.sforce.com">
<Header>
<QueryOptions>
<batchSize>
2000
</batchSize>
</QueryOptions>
<SessionHeader xmlns="urn:enterprise.soap.sforce.com">
<sessionId>
XXXXXX
</sessionId>
</SessionHeader>
</Header>
<Body>
<query xmlns="urn:enterprise.soap.sforce.com">
<queryString>
SELECT Id FROM Account LIMIT 1
</queryString>
</query>
</Body>
</Envelope>
以下のようなレスポンスを得ることができます。このHeader属性に存在している「LimitInfo」の部分がAPI Limitの消費状況のデータになっています。
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:enterprise.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
<Header>
<LimitInfoHeader>
<limitInfo>
<current>
54
</current>
<limit>
15000
</limit>
<type>
API REQUESTS
</type>
</limitInfo>
</LimitInfoHeader>
</Header>
<Body>
<queryResponse>
<result>
<done>
true
</done>
<queryLocator xsi:nil="true" />
<records xsi:type="sf:Account">
<Id>
0010I00002WLs9kQAD
</Id>
</records>
<size>
1
</size>
</result>
</queryResponse>
</Body>
</Envelope>
実は「GetLimitInfo」はそのまま実行すると、上記のようなSOQL(つまり SELECT Id FROM Account LIMIT 1)を実行・レスポンスを取得して、API Limit状況を表示しています。
なので、「GetLimitInfo」を実行することでAPI Limitが見えるんですが、内部的には API Limitを消費して見ていることになるんですね。
それじゃあ本末転倒ではないか?と思われるかもしれないんですが、実はこのAPI リクエストが行われる条件が存在します。
それは「コネクションの状況」「他のSQLの実行状況」です。
例えば、CData Driverを通じて以下のような順番でSQLを実行すると、
SELECT * FROM Account;
Exec GetLimitInfo;
「GetLimitInfo」はAPIリクエストを発行せず、「SELECT * FROM Account」を実行したい時のレスポンスに含まれているAPI Limitを使って表示するようになっています。
実は内部で他のSQL実行時に取得したAPI Limit状況をキャッシュしており、そこを表示するようにアルゴリズムが組まれているんですね。
ただこのキャッシュはコネクション単位で存在するので、以下のように「SELECT * FROM Account」を実行後にコネクションをクローズ・再オープンするとそのキャッシュが無効になるので、その場合は内部的にAPI リクエストが飛んでしまいます。この点は要注意ですね。
SELECT * FROM Account;
// コネクションをクローズ・再オープン
Exec GetLimitInfo;
おわりに
なお、内部ではもうちょっと細かくアルゴリズムが構成されているので、上記はわかりやすい1パターンの例です。
実際の運用ではもう少し異なった動きがあると思いますが、ここでは「GetLimitInfo」を使うことで無駄にAPI Limitを消費しているわけではないというのが伝われば幸いです。
基本的にはクエリ実行後にチェックする、といった運用がベターかもですね。
もしその他、気になることがあればテクニカルサポートまでお気軽にお問い合わせください。
https://jp.cdata.com/support/