Apex API 請求


Salesforce與網絡服務的通信

在Salesforce中可以利用Apex類與遠程站點的網絡服務進行通信。當遠程網絡服務支持REST方法時,開發者可以利用Apex代碼進行數據的操作。

設置遠程站點

在設置界面下,搜索“遠程站點”,點擊“安全性控制”菜單項下的“遠程站點設置”鏈接,即可進入遠程站點的一覽表。在此處可以新建、編輯、刪除遠程站點。這些遠程站點可以作為網絡服務接口。

所有遠程站點界面

Apex REST請求

Apex中可以以HttpRequest類為核心和網絡服務接口進行REST通信。HttpRequest類包括了“setEndpoint()”、“setMethod()”、“setHeader()”、“setBody()”等函數。

假設有一個網絡服務接口“https://example.service.com/laguages”,可以對編程語言的名字進行操作。當執行GET請求時,會給出一個json的結果,包含了一個“languages”數組,里面是若干“language”對象。

GET請求

用以下代碼可以實現GET請求:

public class LanguageCallouts {
    public static HttpResponse makeGetCallout() {
        Http http = new Http();

        HttpRequest request = new HttpRequest();
        // 設置網絡服務接口的地址
        request.setEndpoint('https://example.service.com/laguages');
        // 設置REST方法
        request.setMethod('GET');

        // 發送HTTP請求
        HttpResponse response = http.send(request);

        // 檢查HTTP通信結果狀態代碼
        if (response.getStatusCode() == 200) {
            // 將通信結果轉化為Map類型變量
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            
            // 對結果進行處理,得到language對象
            List<Object> languages = (List<Object>) results.get('languages');
        }

        return response;
    }
}

POST請求

用以下代碼可以實現POST請求:

public class LanguageCallouts {
    public static HttpResponse makePostCallout() {
        Http http = new Http();

        HttpRequest request = new HttpRequest();

        // 設置網絡服務接口的地址
        request.setEndpoint('https://example.service.com/laguages');
        // 設置REST方法
        request.setMethod('POST');
        // 設置請求的Header,類型為JSON
        request.setHeader('Content-Type', 'application/json;charset=UTF-8');
        // 將一個JSON對象傳入請求的Body,設置編程語言的名字
        request.setBody('{"name":"Apex"}');

        // 發送HTTP請求
        HttpResponse response = http.send(request);

        // 檢查HTTP通信結果狀態代碼
        if (response.getStatusCode() == 201) {
            // 在控制台輸出通信結果   
            System.debug(response.getBody());
        }

        return response;
    }
}

對API請求進行單元測試

在Apex的單元測試中,如果被測試的函數涉及到對網絡服務的請求,則單元測試函數無法真正的連接到網絡服務接口進行數據傳輸。開發者必須建立模擬數據。

Apex中提供了“StaticResourceCalloutMock()”函數和“HttpCalloutMock”接口來對網絡服務接口的請求結果進行模擬

StaticResourceCalloutMock()函數

在使用StaticResourceCalloutMock()函數前需要在系統中建立一個靜態資源,其中預設了網絡服務請求的結果。

比如要測試上面示例代碼中的“makeGetCallout()”函數,則首先在系統中建立一個靜態資源“mockRequestResult”,其中包含一個JSON格式的字符串:

{"languages": ["C", "PHP", "Java"]}

在單元測試函數中,寫入如下代碼:

@isTest
static void testGetCallout() {
    StaticResourceCalloutMock mock = new StaticResourceCalloutMock();

    // 設置靜態資源
    mock.setStaticResource('mockRequestResult');
    // 設置模擬網絡服務請求的返回結果
    mock.setStatusCode(200);
    // 設置模擬網絡服務請求的Header部分
    mock.setHeader('Content-Type', 'application/json;charset=UTF-8');

    // 設置模擬的網絡服務請求
    Test.setMock(HttpCalloutMock.class, mock);

    // 運行要測試的函數
    HttpResponse result = LanguageCallouts.makeGetCallout();

    // 檢查返回的結果。該結果應該與mock中設置的內容相同,也包含了靜態資源里的內容
    System.assertNotEquals(null, result);
    System.assertEquals(200, result.getStatusCode());
    System.assertEquals('application/json;charset=UTF-8', result.getHeader('Content-Type'));
    Map<String, Object> results = (Map<String, Object>) JSON.deserializedUntyped(result.getBody());
    List<Object> languages = (List<Object>) results.get('languages');
    System.assertEquals(3, languages.size());
}

HttpCalloutMock接口

HttpCalloutMock接口的使用方法與StaticResourceCalloutMock()函數類似,不過不需要先建立靜態資源,而需要預先建立一個全局Apex類,該類實現了HttpCalloutMock接口,並預設了網絡服務請求的模擬數據。
比如要測試上面示例代碼中的“makePostCallout()”函數,則首先在系統中建立一個“LanguagesHttpCalloutMock”類,在其中設置:

@isTest
global class LanguagesHttpCalloutMock implements HttpCalloutMOck {
    global HttpResponse response(HttpRequest request) {
        HttpResponse response = new HttpResponse();
        response.setHeader('Content-Type', 'application/json');
        response.setBody('{"languages": ["C", "PHP", "Java", "Apex"]}');
        response.setStatusCode(200);
        return response;
    }
}

在單元測試函數中,寫入如下代碼:

@isTest
static void testPostCallout() {
    // 設置模擬的網絡服務請求
    Test.setMock(HttpCalloutMock.class, new LanguagesHttpCalloutMock());

    // 運行要測試的函數
    HttpResponse result = LanguageCallouts.makePostCallout();

    // 檢查返回的結果
    System.assertEquals(200, result.getStatusCode());
    System.assertEquals('application/json;charset=UTF-8', result.getHeader('Content-Type'));
    String expectedResult = '{"languages": ["C", "PHP", "Java", "Apex"]}';
    System.assertEquals(response.getBody(), expectedResult);
}

Apex類作為網絡服務

Apex類可以被擴展為網絡服務,外部的請求可以通過此類來與Salesforce中的數據進行通信。

將Apex類定義為REST服務類

將Apex類定義為REST服務類只需要以下步驟:

  1. 將類定義為全局類
  2. 將特定注解添加到類和函數的定義
    比如:
@RestResource(urlMapping='/Account/*)
global with sharing class ExampleRestClass {
    @HttpGet
    global static Account getAccount() {
        // ...
    }
}

代碼講解:

  1. 在類的定義上方,添加了@RestResource注解,並定義了“urlMapping”屬性。這樣,該Salesforce中的特定URL便可以作為REST服務的端點。在此示例中,外部請求通過URL “https://xxx.salesforce.com/services/apexrest/Account/” 就可以調用此類。需要注意的是,“urlMapping”屬性是區分大小寫的。
  2. 在函數的上方,添加了@HttpGet注解,說明此類相應“GET”方法。同樣,基於標准的REST方法,還有其他注解:@HttpPost, @HttpDelete, @HttpPut, @HttpPatch等。

將Apex類定義為SOAP服務類

將Apex類定義為SOAP服務類和定義為REST服務類的步驟類似,只不過不需要注解,而是直接用“webservice”關鍵字定義函數。比如:

global with sharing class ExampleSoapClass {
    webservice static Account getAccount(String Id) {
        // ...
    }
}

從設置界面的“Apex 類”鏈接進入Apex類一覽表,再進入該類的詳細信息頁面,即可下載該類對應的WSDL文件,用於SOAP請求。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM