外部Webサービスへのコールアウト


外部Webサービスへのコールアウト

Apex RestAPI コールアウト を使用して外部Webサービスと通信を行います。
例として、Google Geocoding APIを使用して、住所から地理位置情報(緯度経度)を取得します。

リモートサイト設定

Apex HTTP コールアウトを利用するためには、エンドポイントをリモートサイトの設定に登録する必要があります。
[設定] - [セキュリティ] - [リモートサイトの設定]1から新規リモートサイトボタンをクリックし、URLを設定します。

参照

Apexクラスの作成

コールアウトにはHttp、HttpRequest、HttpResponseなどのクラスを使用します。

店舗(Store__c)オブジェクトの住所(Address__c、テキスト)に入力された値から、Google Geocoding APIで地理位置情報を取得し、緯度経度(Location__c、地理位置情報)に設定するコールアウトの例↓。

public with sharing class LocationHttpCallout {
    @future(callout=true)
    public static void putLocation(Id storeId) {
        Store__c obj = [SELECT Address__c FROM Store__c WHERE Id = :storeId];
        if (obj.Address__c == null) { return; }

        String address = EncodingUtil.urlEncode(obj.Address__c, 'UTF-8');
        String endpoint = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + address + '&key=' + System.label.GoogleApiKey;

        HttpRequest req = new HttpRequest();
        req.setEndpoint(endpoint);
        req.setMethod('GET');
        req.setTimeout(2000); // タイムアウト(ms)。デフォルトは10秒。
        System.debug(LoggingLevel.INFO, '----request----');
        System.debug(LoggingLevel.INFO, 'ENDPOINT: ' + endpoint);

        try {
            HttpResponse res = new Http().send(req);
            System.debug(LoggingLevel.INFO, '----responce----');
            System.debug(LoggingLevel.INFO, 'STATUS: '      + res.getStatus());
            System.debug(LoggingLevel.INFO, 'STATUS_CODE: ' + res.getStatusCode());
            System.debug(LoggingLevel.INFO, 'BODY: '        + res.getBody());

            if (res.getStatusCode() == 200) {
                Location loc = toLocation(res.getBody());
                obj.Location__Latitude__s  = loc.getLatitude();
                obj.Location__Longitude__s = loc.getLongitude();
                update obj;
            }
        } catch (CalloutException e) {
            System.debug(LoggingLevel.ERROR, e);
        }
    }


    private static Location toLocation(String jsonBody) {
        Map<String, Object> resMap   = (Map<String, Object>) JSON.deserializeUntyped(jsonBody);
        List<Object>        results  = (List<Object>) resMap.get('results');
        Map<String, Object> result   = (Map<String, Object>) results[0];
        Map<String, Object> geometry = (Map<String, Object>) result.get('geometry');
        Map<String, Object> loc      = (Map<String, Object>) geometry.get('location');
        Decimal latitude = (Decimal) loc.get('lat');
        Decimal longtude = (Decimal) loc.get('lng');

        return Location.newInstance(latitude, longtude);
    }
}

留意事項

トリガからの呼び出しには非同期である必要があります。
エラー: System.CalloutException: Callout from triggers are currently not supported.

非同期でコールアウトを行うには@future(callout=true)が必要です。
エラー: System.CalloutException: Callout not allowed from this future method. Please enable callout by annotating the future method. eg: @Future(callout=true)

一括処理からの呼び出しには、Database.AllowsCalloutsインターフェースを実装する必要があります。
エラー: Too many callouts: 1

参考


  1. Classic → [設定] - [管理] - [セキュリティのコントロール] - [リモートサイトの設定]