CData Software Blog

クラウド連携のCData Software の技術ブログです。

Salesforce API Limitをチェックするためのストアドプロシージャ「GetLimitInfo」が追加されました:CData Salesforce Driver

f:id:sugimomoto:20210607231711p:plain こんにちは。CData Software Japanリードエンジニアの杉本です。

以前このBlogでSalesforceAPI Limitについて解説したことがありました。

www.cdatablog.jp

この記事の中で、この合計API要求数要求の割当および消費状況の確認方法は、Salesforce の「設定」→「システムの概要」にある「API 使用状況」で見れるよ-、と記載していたのですが

f:id:sugimomoto:20210607231127p:plain

プログラムやCData Driver を使っている過程でAPI Limitを監視したい、確認したいという要望もあるかと思います。

実は最近そのAPI Limit状況を確認するための新しい機能が追加されたので、今回の記事ではその新機能を紹介したいと思います。

GetLimitInfo ストアドプロシージャについて

新しく追加された機能は「GetLimitInfo」というストアドプロシージャです。

cdn.cdata.com

ODBCJDBCADO.NET など全ドライバー共通の機能です。

www.cdata.com

使い方はとても簡単で以下のようにSQLでストアドプロシージャを実行するだけです。

Exec GetLimitInfo;

実行すると以下のように現在のAPI Limit消費状況「Current」と、API Limitの「Limit」が表示されます。

f:id:sugimomoto:20210607231223p:plain

これでプログラムからも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://www.cdata.com/jp/support/submit.aspx