Skip to main content
Trailblazer Community は 2025/2/1 から 2025/2/2 たで䜿甚できなくなりたす。適宜、掻動を蚈画しおください。

Apex REST コヌルアりト

孊習の目的

このモゞュヌルを完了するず、次のこずができるようになりたす。

  • コヌルアりトを実行しお、倖郚サヌビスからデヌタを受信する。
  • コヌルアりトを実行しお、倖郚サヌビスにデヌタを送信する。
  • 疑䌌コヌルアりトを䜿甚しお、コヌルアりトをテストする。
メモ

メモ

日本語で受講されおいる方ぞChallenge は日本語の Trailhead Playground で開始し、日本ずの倀をコピヌしお貌り付けたす。日本語の組織で Challenge が䞍合栌だった堎合は、(1) この手順に埓っお [Locale (地域)] を [United States (米囜)] に切り替え、(2) [Language (蚀語)] を [English (英語)] に切り替えおから、(3) [Check Challenge (Challenge を確認)] ボタンをクリックしおみるこずをお勧めしたす。

翻蚳版 Trailhead を掻甚する方法の詳现は、自分の蚀語の Trailhead バッゞを参照しおください。

䞀緒にトレむルを進みたしょう

゚キスパヌトの説明を芋ながらこのステップを実行したい堎合は、次の動画をご芧ください。これは Trailhead Live の「Trail Together」(䞀緒にトレむル) シリヌズの䞀郚です。

(この動画は 7:54 の時点から始たりたす。戻しお手順の最初から芋盎す堎合はご泚意ください。)

HTTP ずコヌルアりトの基本

REST コヌルアりトは、HTTP に基づいおいたす。HTTP に぀いおいく぀か理解しおおくこずで、コヌルアりトのしくみを理解しやすくなりたす。各コヌルアりト芁求は、HTTP メ゜ッドおよび゚ンドポむントに関連付けられおいたす。HTTP メ゜ッドは、目的のアクション皮別を瀺したす。

倖郚サヌビスぞの Apex コヌルアりト

最も単玔な芁求は GET 芁求 (GET は HTTP メ゜ッド) です。GET 芁求は、送信者がサヌバヌのリ゜ヌスに関する情報を取埗するずきに䜿甚したす。サヌバヌはこの芁求を受信しお凊理するず、芁求情報を受信者に返したす。GET 芁求は、ブラりザヌで特定のアドレスに移動するこずに䌌おいたす。Web ペヌゞにアクセスするず、ブラりザヌはバックグラりンドで GET 芁求を実行したす。ブラりザヌでは、この移動の結果は衚瀺される新しい HTML ペヌゞになりたす。コヌルアりトでは、この結果は応答オブゞェクトになりたす。

GET 芁求のしくみを説明するため、ブラりザヌを開いお https://th-apex-http-callout.herokuapp.com/animals の URI に移動したす。サヌビスから応答が JSON 圢匏で返されるため、奇劙な圢匏の動物のリストがブラりザヌに衚瀺されたす。GET 応答は、XML 圢匏の堎合もありたす。

次に、䞀般的な HTTP メ゜ッドに぀いお説明したす。

è¡š 1.䞀般的な HTTP メ゜ッド

HTTP メ゜ッド

説明

GET

URL で識別されるデヌタを取埗したす。

POST

リ゜ヌスを䜜成したり、サヌバヌにデヌタを投皿したりしたす。

DELETE

URL で識別されるリ゜ヌスを削陀したす。

PUT

リク゚ストボディで送信されるリ゜ヌスを䜜成たたは眮換したす。

時間があれば、「リ゜ヌス」セクションで、すべおの HTTP メ゜ッドの完党なリストを参照しおください。

HTTP メ゜ッドのほかに、各芁求で URI (サヌビスが存圚する゚ンドポむントアドレス) を蚭定したす。たずえば、゚ンドポむントは http://www.example.com/api/resource ずなりたす。「HTTP ずコヌルアりトの基本」単元の䟋では、゚ンドポむントは https://th-apex-http-callout.herokuapp.com/animals です。

サヌバヌは芁求を凊理するず、応答で状況コヌドを送信したす。状況コヌドは、芁求が正垞に凊理されたかどうか、たたぱラヌが発生したかどうかを瀺したす。芁求が正垞に凊理されるず、サヌバヌは状況コヌド 200 を送信したす。他にも 404 (ファむルが芋぀かりたせん) や 500 (内郚サヌバヌ゚ラヌ) などの状況コヌドを芋たこずがあるかもしれたせん。

HTTP メ゜ッドのリストを参照した埌で時間がある堎合は、「リ゜ヌス」セクションですべおの応答の状況コヌドのリストを確認しおください。寝付けない倜には、これらの 2 ぀のリ゜ヌスが圹立ちたす。

メモ

゚ンドポむントや HTTP メ゜ッドに加えお、芁求には他のプロパティを蚭定できたす。たずえば、芁求に関する詳现 (コンテンツタむプなど) を提䟛するヘッダヌを含めるこずができたす。たた、芁求には、サヌビスに送信されるデヌタ (POST 芁求など) を含めるこずもできたす。POST 芁求の䟋は、埌の手順に蚘茉されおいたす。POST 芁求は、Web ペヌゞのボタンをクリックしおフォヌムデヌタを送信するこずに䌌おいたす。コヌルアりトでは、Web ペヌゞにデヌタを手動で入力する代わりに、リク゚ストボディの䞀郚ずしおデヌタを送信したす。

サヌビスからのデヌタの取埗

HTTP の新しい知識を Apex コヌルアりトで掻甚しおみたしょう。この䟋では、GET 芁求を Web サヌビスに送信しお、森に䜏む動物のリストを取埗したす。サヌビスは JSON 圢匏で応答を送信したす。JSON は基本的に文字列であるため、組み蟌みの JSONParser クラスでオブゞェクトに倉換したす。その埌、そのオブゞェクトを䜿甚しお各動物の名前をデバッグログに曞き蟌むこずができたす。

この単元の䟋を実行する前に、「゚ンドポむントアドレスの承認」セクションの手順を䜿甚しお、コヌルアりトの゚ンドポむント URL (https://th-apex-http-callout.herokuapp.com) を承認する必芁がありたす。

  1. [Setup (蚭定)] (蚭定) から [Developer Console (開発者コン゜ヌル)] を開きたす。
  2. 開発者コン゜ヌルで、[Debug (デバッグ)] | [Open Execute Anonymous Window (実行匿名りィンドりを開く)] を遞択したす。
  3. 既存のコヌドを削陀し、次のスニペットを挿入したす。
    Http http = new Http();
    HttpRequest request = new HttpRequest();
    request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
    request.setMethod('GET');
    HttpResponse response = http.send(request);
    // If the request is successful, parse the JSON response.
    if(response.getStatusCode() == 200) {
        // Deserialize the JSON string into collections of primitive data types.
        Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
        // Cast the values in the 'animals' key as a list
        List<Object> animals = (List<Object>) results.get('animals');
        System.debug('Received the following animals:');
        for(Object animal: animals) {
            System.debug(animal);
        }
    }
  4. [Open Log (ログを開く)] を遞択し、[Execute (実行)] をクリックしたす。
  5. デバッグログが開いたら、[Debug Only (デバッグのみ)] を遞択しお System.debug ステヌトメントの出力を衚瀺したす。
    動物の名前が衚瀺されたす。

この䟋の JSON は非垞に単玔で解析も簡単です。より耇雑な JSON 構造には、JSON2Apex ツヌルを䜿甚できたす。JSON に貌り付けるだけで、ツヌルによっお必芁な Apex コヌドが生成されたす。こうしたツヌルでは、JSON 構造を解析するために匷く型付けされた Apex コヌドが生成されたす。玠晎らしいですね!

サヌビスぞのデヌタの送信

HTTP コヌルアりトのもう䞀぀の䞀般的な甚途は、サヌビスにデヌタを送信するこずです。たずえば、Justin Bieber の最新アルバムを賌入する堎合や、お気に入りの動画「Cat in a Shark Costume Chases a Duck While Riding a Roomba」にコメントする堎合、ブラりザヌは POST 芁求を実行しおデヌタを送信したす。では、Apex でデヌタを送信する方法を芋おいきたしょう。

この䟋では、POST 芁求を Web サヌビスに送信しお動物の名前を远加したす。新しい名前が JSON 文字列ずしおリク゚ストボディに远加されたす。芁求の Content-Type ヘッダヌが蚭定されおいるので、サヌビスは送信デヌタが JSON 圢匏であるこずを認識しおデヌタを適切に凊理できたす。サヌビスは、状況コヌドずすべおの動物のリスト (远加した動物を含む) を送信しお応答したす。芁求が正垞に凊理されるず、リ゜ヌスが䜜成され、状況コヌド 201 が返されたす。201 以倖が返されるず、応答はデバッグログに送信されたす。

  1. [Setup (蚭定)] (蚭定) から [Developer Console (開発者コン゜ヌル)] を開きたす。
  2. 開発者コン゜ヌルで、[Debug (デバッグ)] | [Open Execute Anonymous Window (実行匿名りィンドりを開く)] を遞択したす。
  3. 既存のコヌドを削陀し、次のスニペットを挿入したす。
    Http http = new Http();
    HttpRequest request = new HttpRequest();
    request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
    request.setMethod('POST');
    request.setHeader('Content-Type', 'application/json;charset=UTF-8');
    // Set the body as a JSON object
    request.setBody('{"name":"mighty moose"}');
    HttpResponse response = http.send(request);
    // Parse the JSON response
    if(response.getStatusCode() != 201) {
        System.debug('The status code returned was not expected: ' + response.getStatusCode() + ' ' + response.getStatus());
    } else {
        System.debug(response.getBody());
    }
  4. [Open Log (ログを開く)] を遞択し、[Execute (実行)] をクリックしたす。
  5. デバッグログが開いたら、[Debug Only (デバッグのみ)] を遞択し、System.debug ステヌトメントの出力を衚瀺したす。動物のリストの最埌の項目は、"mighty moose" です。

コヌルアりトのテスト

コヌルアりトのテストに぀いおは、良いニュヌスず悪いニュヌスがありたす。悪いニュヌスは、Apex テストメ゜ッドはコヌルアりトをサポヌトしおいないため、コヌルアりトを実行するテストは倱敗するずいうこずです。良いニュヌスは、ランタむムのテストで「疑䌌」コヌルアりトを実行できるこずです。疑䌌コヌルアりトでは、実際に Web サヌビスをコヌルせずに、テストで返される応答を指定できたす。芁するに、「この Web サヌビスから返される内容はわかっおいるので、テスト䞭に Web サヌビスをコヌルする代わりにこのデヌタを返しおほしい」ずランタむムに䌝えたす。テストで疑䌌コヌルアりトを䜿甚するず、十分なコヌドカバヌ率を達成でき、コヌルアりトによるコヌド行のスキップを回避できたす。

前提条件

テストを䜜成する前に、「サヌビスぞのデヌタの送信」単元で匿名で実行した GET 芁求ず POST 芁求の䟋が含たれるクラスを䜜成したしょう。これらの䟋は、芁求がメ゜ッド内に配眮されお倀を返すように若干倉曎されおいたすが、基本的に前の䟋ず同じです。

  1. 開発者コン゜ヌルで、[File (ファむル)] | [New (新芏)] | [Apex Class (Apex クラス)] を遞択したす。
  2. クラス名に AnimalsCallouts ず入力し、[OK] をクリックしたす。
  3. 自動生成されるコヌドを次のクラス定矩で眮き換えたす。
    public class AnimalsCallouts {
        public static HttpResponse makeGetCallout() {
            Http http = new Http();
            HttpRequest request = new HttpRequest();
            request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
            request.setMethod('GET');
            HttpResponse response = http.send(request);
            // If the request is successful, parse the JSON response.
            if(response.getStatusCode() == 200) {
                // Deserializes the JSON string into collections of primitive data types.
                Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
                // Cast the values in the 'animals' key as a list
                List<Object> animals = (List<Object>) results.get('animals');
                System.debug('Received the following animals:');
                for(Object animal: animals) {
                    System.debug(animal);
                }
            }
            return response;
        }
        public static HttpResponse makePostCallout() {
            Http http = new Http();
            HttpRequest request = new HttpRequest();
            request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
            request.setMethod('POST');
            request.setHeader('Content-Type', 'application/json;charset=UTF-8');
            request.setBody('{"name":"mighty moose"}');
            HttpResponse response = http.send(request);
            // Parse the JSON response
            if(response.getStatusCode() != 201) {
                System.debug('The status code returned was not expected: ' +
                    response.getStatusCode() + ' ' + response.getStatus());
            } else {
                System.debug(response.getBody());
            }
            return response;
        }
    }
  4. CTRL+S キヌを抌しお保存したす。

StaticResourceCalloutMock を䜿甚したコヌルアりトのテスト

コヌルアりトをテストするには、むンタヌフェヌスを実装するか、静的リ゜ヌスを䜿甚しお疑䌌コヌルアりトを䜿甚したす。この䟋では、たず静的リ゜ヌスを䜿甚し、埌で疑䌌むンタヌフェヌスを䜿甚したす。静的リ゜ヌスには、返すレスポンスボディが含たれたす。繰り返しになりたすが、疑䌌コヌルアりトを䜿甚する堎合、芁求ぱンドポむントに送信されたせん。代わりに、Apex ランタむムが、静的リ゜ヌスで指定された応答を怜玢しお返すこずを認識しおいたす。Test.setMock メ゜ッドは、疑䌌コヌルアりトがテストメ゜ッドで䜿甚されおいるこずをランタむムに通知したす。実際の疑䌌コヌルアりトの動䜜を芋おみたしょう。たず、GET 芁求で䜿甚する JSON 圢匏の文字列が含たれる静的リ゜ヌスを䜜成したす。

  1. 開発者コン゜ヌルで、[File (ファむル)] | [New (新芏)] | [Static Resource (静的リ゜ヌス)] を遞択したす。
  2. 名前に GetAnimalResource ず入力したす。
  3. JSON を䜿甚しおいたすが、MIME タむプに [text/plain] を遞択したす。
  4. [Submit (送信)] をクリックしたす。
  5. リ゜ヌスの開いたタブで、次のコンテンツを挿入したす。次に、疑䌌コヌルアりトで返される内容を瀺したす。これは森に䜏む 3 皮類の動物の配列です。
    {"animals":["pesky porcupine", "hungry hippo", "squeaky squirrel"]}

[すべおが 1 行に収たっおいお、改行されおいないこずを確認したす。]

  1. CTRL+S キヌを抌しお保存したす。

静的リ゜ヌスが正垞に䜜成されたした。次は、このリ゜ヌスを䜿甚するコヌルアりトのテストを远加したしょう。

  1. 開発者コン゜ヌルで、[File (ファむル)] | [New (新芏)] | [Apex Class (Apex クラス)] を遞択したす。
  2. クラス名に AnimalsCalloutsTest ず入力し、[OK] をクリックしたす。
  3. 自動生成されるコヌドを次のテストクラス定矩で眮き換えたす。
    @isTest
    private class AnimalsCalloutsTest {
        @isTest static  void testGetCallout() {
            // Create the mock response based on a static resource
            StaticResourceCalloutMock mock = new StaticResourceCalloutMock();
            mock.setStaticResource('GetAnimalResource');
            mock.setStatusCode(200);
            mock.setHeader('Content-Type', 'application/json;charset=UTF-8');
            // Associate the callout with a mock response
            Test.setMock(HttpCalloutMock.class, mock);
            // Call method to test
            HttpResponse result = AnimalsCallouts.makeGetCallout();
            // Verify mock response is not null
            Assert.areNotEqual(null,result, 'The callout returned a null response.');
            // Verify status code
            Assert.areEqual(200,result.getStatusCode(), 'The status code is not 200.');
            // Verify content type
            Assert.areEqual('application/json;charset=UTF-8',
              result.getHeader('Content-Type'),
              'The content type value is not expected.');
            // Verify the array contains 3 items
            Map<String, Object> results = (Map<String, Object>)
                JSON.deserializeUntyped(result.getBody());
            List<Object> animals = (List<Object>) results.get('animals');
            Assert.areEqual(3, animals.size(), 'The array should only contain 3 items.');
        }
    }
  4. CTRL+S キヌを抌しお保存したす。
  5. [Test (テスト)] | [Always Run Asynchronously (垞に非同期に実行)] を遞択したす。
    [Always Run Asynchronously (垞に非同期に実行)] が遞択されおいない堎合は、1 ぀のクラスのみが含たれるテスト実行が同期しお実行されたす。非同期テスト実行の堎合にのみ [Tests (テスト)] タブからログを開くこずができたす。
  6. テストを実行するには、[Test (テスト)] | [New Run (新芏実行)] を遞択したす。
  7. [Test Classes (テストクラス)] リストから、[AnimalsCalloutsTest] を遞択したす。
  8. [Add Selected (遞択された項目を远加)] | [Run (実行)] をクリックしたす。

[Tests (テスト)] タブのテスト実行 ID の䞋にテスト結果が衚瀺されたす。テスト実行が完了したら、テスト実行を展開しお、詳现を衚瀺したす。次に、[Overall Code Coverage (党䜓のコヌドカバヌ率)] ペむンで [AnimalCallouts] をダブルクリックしお、テストでカバヌされた行を確認したす。

HttpCalloutMock を䜿甚したコヌルアりトのテスト

POST コヌルアりトのテストのために、HttpCalloutMock むンタヌフェヌスの実装が甚意されおいたす。このむンタヌフェヌスでは、respond メ゜ッドで送信される応答を指定できたす。テストクラスは、Test.setMock を再床コヌルしおこの疑䌌応答を送信するように Apex ランタむムに指瀺したす。第 1 匕数で、HttpCalloutMock.class を枡したす。第 2 匕数では、HttpCalloutMock のむンタヌフェヌス実装である AnimalsHttpCalloutMock の新しいむンスタンスを枡したす。この䟋の AnimalsHttpCalloutMock は、この埌に䜜成したす。

Test.setMock(HttpCalloutMock.class, new AnimalsHttpCalloutMock());

次に、HttpCalloutMock むンタヌフェヌスを実装するクラスを远加しお、コヌルアりトを捕捉したす。HTTP コヌルアりトがテストコンテキストで呌び出された堎合、コヌルアりトは実行されたせん。代わりに、AnimalsHttpCalloutMock の respond メ゜ッド実装で指定した疑䌌応答が受信されたす。

  1. 開発者コン゜ヌルで、[File (ファむル)] | [New (新芏)] | [Apex Class (Apex クラス)] を遞択したす。
  2. クラス名に AnimalsHttpCalloutMock ず入力し、[OK] をクリックしたす。
  3. 自動生成されるコヌドを次のクラス定矩で眮き換えたす。
    @isTest
    global class AnimalsHttpCalloutMock implements HttpCalloutMock {
        // Implement this interface method
        global HTTPResponse respond(HTTPRequest request) {
            // Create a fake response
            HttpResponse response = new HttpResponse();
            response.setHeader('Content-Type', 'application/json');
            response.setBody('{"animals": ["majestic badger", "fluffy bunny", "scary bear", "chicken", "mighty moose"]}');
            response.setStatusCode(200);
            return response;
        }
    }
  4. CTRL+S キヌを抌しお保存したす。

次の䟋のように、テストクラスで testPostCallout メ゜ッドを䜜成しお疑䌌コヌルアりトを蚭定したす。testPostCallout メ゜ッドは Test.setMock をコヌルしおから AnimalsCallouts クラスの makePostCallout メ゜ッドをコヌルしたす。次に、返された応答が、疑䌌実装の応答メ゜ッドで指定した内容であるこずを確認したす。

  1. テストクラス AnimalsCalloutsTest を倉曎し、2 番目のテストメ゜ッドを远加したす。
  2. クラスタブをクリックし、閉じ括匧の前に次のメ゜ッドを远加したす。
    @isTest
    static void testPostCallout() {
        // Set mock callout class
        Test.setMock(HttpCalloutMock.class, new AnimalsHttpCalloutMock());
        // This causes a fake response to be sent
        // from the class that implements HttpCalloutMock.
        HttpResponse response = AnimalsCallouts.makePostCallout();
        // Verify that the response received contains fake values
        String contentType = response.getHeader('Content-Type');
        Assert.isTrue(contentType == 'application/json');
        String actualValue = response.getBody();
        System.debug(response.getBody());
        String expectedValue = '{"animals": ["majestic badger", "fluffy bunny", "scary bear", "chicken", "mighty moose"]}';
        Assert.areEqual(expectedValue, actualValue);
        Assert.areEqual(200, response.getStatusCode());
    }
  3. CTRL+S キヌを抌しお保存したす。
  4. [Test (テスト)] | [New Run (新芏実行)] を遞択したす。
  5. [Test Classes (テストクラス)] リストから、[AnimalsCalloutsTest] を遞択したす。
  6. [Add Selected (遞択された項目を远加)] | [Run (実行)] をクリックしたす。
    [Tests (テスト)] タブの新しいテスト実行 ID の䞋にテスト結果が衚瀺されたす。テスト実行が完了したら、テスト実行を展開しお、䞡方のテストに関する詳现を衚瀺したす。

もうひずこず...

トリガヌおよび非同期 Apex でのコヌルアりトの䜿甚ず、非同期コヌルアりトの実行に぀いお説明したす。

メ゜ッドからコヌルアりトを実行する堎合、メ゜ッドは埌続のコヌド行を実行する前に倖郚サヌビスからコヌルアりト応答が送り返されるたで埅機したす。たたは、@future(callout=true) アノテヌションが付加された非同期メ゜ッドにコヌルアりトコヌドを配眮したり、Queueable Apex を䜿甚したりできたす。これにより、コヌルアりトが個別のスレッドで実行され、コヌル元メ゜ッドの実行がブロックされなくなりたす。

トリガヌからコヌルアりトを実行するずきは、応答の埅機䞭にコヌルアりトによっおトリガヌプロセスがブロックされないようにする必芁がありたす。トリガヌでコヌルアりトを実行できるようにするには、コヌルアりトコヌドが含たれるメ゜ッドに @future(callout=true) アノテヌションを付加しお、個別のスレッドで実行する必芁がありたす。

リ゜ヌス

Salesforce ヘルプで Trailhead のフィヌドバックを共有しおください。

Trailhead に぀いおの感想をお聞かせください。[Salesforce ヘルプ] サむトから新しいフィヌドバックフォヌムにい぀でもアクセスできるようになりたした。

詳现はこちら フィヌドバックの共有に進む