> For the complete documentation index, see [llms.txt](https://help.smallbuilder.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.smallbuilder.com/ko/smallbuilder-line-items/builder/setup/datasource/external.md).

# 고급

**주로 외부 서버에서 데이터를 조회하여 같이 표현해주고 싶을 때 사용됩니다. 사용자가 작성한 Apex Class를 이용해 데이터소스를 가져오기 때문에 내부 데이터소스에 비해 자유롭게 데이터를 가져올 수 있는 장점이 있습니다.**

<figure><img src="/files/OE34qi4D0hlZeENfi65H" alt=""><figcaption></figcaption></figure>

예를 들어 외부 서버에서 실시간 재고를 가져와 화면에 같이 표시하고 싶은 경우 Apex Class에서 Rest API 코드를 작성하여 외부 데이터소스에 지정하면 Line-Item Configurator에서 해당 데이터를 보실 수 있습니다.

* [**속성**](#undefined)

  External 데이터소스를 사용하기 위한 각 속성입니다.
* [**Apex Class 작성**](#apex-class)

  External 데이터소스를 사용하기 전 Apex Class를 먼저 작성해야 합니다. Package에서 제공하는 `SBLD.DataSourceService.Fetchable` 인터페이스를 작성하려는 Apex Class에 `implements` 하여 구현합니다.
* [**예시**](#undefined-1)

  준비중입니다.

***

### 속성

External 데이터소스를 사용하기 위한 각 속성입니다.

<table><thead><tr><th width="261">항목</th><th width="388">설명</th><th>필수</th></tr></thead><tbody><tr><td>Apex Class Name</td><td>외부데이터를 가져올 때 사용하는 클래스의 이름입니다.</td><td><mark style="color:red;">✔️</mark></td></tr><tr><td>Key Field</td><td>DataSource를 통해 가져온 데이터를 매핑시키기 위한 field API 이름을 나타냅니다.</td><td><mark style="color:red;">✔️</mark></td></tr><tr><td>Parent Field Parameters</td><td>DataSource의 Type이 External일 경우 Parent Object의 Field 중 Parameter로 넘겨줄 Field를 나타냅니다.</td><td></td></tr><tr><td>Lookup Field Parameters</td><td>DataSource의 Type이 External일 경우 Lookup Object의 Field 중 Parameter로 넘겨줄 Field를 나타냅니다.</td><td></td></tr><tr><td>Active</td><td>DataSource의 활성, 비활성 여부입니다.</td><td><mark style="color:red;">✔️</mark></td></tr></tbody></table>

### Apex Class 작성

External 데이터소스를 사용하기 전 Apex Class를 먼저 작성해야 합니다. Package에서 제공하는 `SBLD.DataSourceService.Fetchable` 인터페이스를 작성하려는 Apex Class에 `implements` 하여 구현합니다.

`SBLD.DataSourceService.Fetchable` 클래스를 `implements` 하여 `execute()` 메서드를 구현합니다.

{% code title="DataSourceServiceMock.cls" lineNumbers="true" %}

```apex
global with sharing class DataSourceServiceMock implements SBLD.DataSourceService.Fetchable {
    /***
     * @description SBLD.DataSourceService.Fetchable execute() 정의
     * @param param SBLD.DataSourceService.Parameter형 파라미터
     *              DataSource에서 설정한 
     * @return Map<Object, SObject>
     ****/
    global SBLD.DataSourceService.Result execute(SBLD.DataSourceService.Parameter param) {
        SBLD.DataSourceService.Result result = new SBLD.DataSourceService.Result();
        /**
         *  @method DataSourceService.Parameter gets()
         *  @param  String 형 Parent, Lookup 중 선택 (대소문자 구분 없음)
         *  @return List<SObject>
         **/
        SObject parentRecord = null;
        List<SObject> lookupRecords = new List<SObject>();
        // Parent 관련 파라미터를 가져옵니다.
        if(param.gets('parent')<>null && !param.gets('parent').isEmpty()) {
            parentRecord = param.gets('parent')[0];
        }
        // Lookup 관련 파라미터를 가져옵니다.
        if(param.gets('lookup')<>null && !param.gets('lookup').isEmpty()) {
            listLookupParameters = param.gets('lookup');
        }
        /**
         * 성공 시, External 결과값을 설정합니다.
         **/
        for(SObject sobj : lookupRecords) {
            /**
             * Internal의 Action과 동일하게 DataSource의 값을 
             * Lookup 또는 Line-Item 필드에 매핑하는 작업을 
             **/
            SBLD.DataSourceServiceAction action = new SBLD.DataSourceServiceAction();
            // 1. External에 설정한 External Key 값
            action.setKeyValue(sobj.get('Id')); // Product Code
            // 2. External에서 가져온 값을 Lookup 또는 Junction 필드에 매핑합니다.
            Map<String, Object> mapPopulatedField = sobj.getPopulatedFieldsAsMap();
            for(String fieldName : mapPopulatedField.keySet()) {
                action.putSourceToTargetField(mapPopulatedField.get(fieldName), fieldName);
            }
            // 3. DataSourceService.Result에 Action을 추가합니다.
            result.addAction(action);
        }
        return result;
    }
}
```

{% endcode %}

`SBLD.DataSourceService.Parameter`에서 `gets()` 메서드를 통해 Line-Item Configurator의 Parent 또는 Lookup 정보를 가져올 수 있습니다.

{% code lineNumbers="true" %}

```apex
global SBLD.DataSourceService.Result execute(SBLD.DataSourceService.Parameter param) {
    SObject parentRecord = null;
    List<SObject> lookupRecords = new List<SObject>();
    // Parent 관련 파라미터를 가져옵니다.
    if(param.gets('parent')<>null && !param.gets('parent').isEmpty()) {
        parentRecord = param.gets('parent')[0];
    }
    // Lookup 관련 파라미터를 가져옵니다.
    if(param.gets('lookup')<>null && !param.gets('lookup').isEmpty()) {
        listLookupParameters = param.gets('lookup');
    }
    ...
}
```

{% endcode %}

Line-Item Configurator로 결과값을 전달하기 위해 아래 클래스를 이용합니다.

### **SBLD.DataSourceServiceAction Class**

대상(Lookup 또는 Line-Item)의 행마다 Action을 지정합니다. Action은 데이터소스 값을 Lookup 또는 Line-Item 필드에 매핑하는 작업입니다.

* **setKeyValue(Object keyValue)**\
  Lookup 또는 Line-Item의 대상 레코드를 찾기 위한 Key값을 설정합니다.
* **putSourceToTargetField(Object sourceValue, String targetField)**\
  데이터소스 값을 Lookup 또는 Line-Item 필드에 할당합니다.

### **SBLD.DataSourceService.Result Class**

매핑이 완료된 Action을 리턴 값에 추가하는 작업입니다.

* **addAction(SBLD.DataSourceServiceAction action)**\
  SBLD.DataSourceService.Result 인스턴스에 Action을 추가합니다.

{% code lineNumbers="true" %}

```apex
...
SBLD.DataSourceService.Result result = new SBLD.DataSourceService.Result();
for(Object objResponse : listResponses) {
    Map<String, Object> mapResponse = (Map<String, Object>)objResponse;

    SBLD.DataSourceServiceAction action = new SBLD.DataSourceServiceAction();
    // 데이터소스에서 설정한 Key 필드에 알맞는 값
    action.setKeyValue(mapResponse.get('Id')); // Product Code
    // 데이터소스에서 가져온 값을 Lookup 또는 Line-Item 필드에 넣기
    action.putSourceToTargetField(mapResponse.get('inventory'), 'Inventory__c');
    // SBLD.DataSourceService.Result에 Action을 추가한다.
    result.addAction(action);
}
return result;
```

{% endcode %}

### 예시

준비중입니다.
