# Advanced DataSources

**External DataSources are mostly used when you want to retrieve data from an external server and display it together with your Salesforce data. Since the data is retrieved using a user-created Apex Class, it has the advantage of being able to retrieve data more freely than with internal Salesforce data sources.**

<figure><img src="/files/UmskvoJWv3Kor5SNxfn9" alt="" width="563"><figcaption></figcaption></figure>

***

{% stepper %}
{% step %}

#### Writing an Apex Class

When writing an Apex class, you must implement the interface provided by SmallBuilder.
{% endstep %}

{% step %}

#### Advanced Data Source Configuration

Once the Apex class implementation is complete, proceed with the Advanced Data Source Configuration in the builder.
{% endstep %}
{% endstepper %}

For example, if you want to fetch real-time inventory numbers from an external server or ERP system, then you can write Rest API code in an Apex Class and point it to an external data source. Then, you will be able to view that data in the Line-Item Configurator.

* [**Properties**](#properties)

  Describing properties of external DataSources.
* [**Creating an Apex Class**](#creating-an-apex-class)

  Before you can use an external data source, you must write an Apex Class. Implement the `SBLD.DataSourceService.Fetchable` interface provided by the package by implementing it in the Apex Class you want to write.
* [**Example**](#example)

  Under construction.

***

### Properties

External DataSource properties are listed below.

<table><thead><tr><th width="261">Item</th><th width="388">Description</th><th>Req.</th></tr></thead><tbody><tr><td>Apex Class Name</td><td>The name of the Apex Class used to import external data.</td><td><mark style="color:red;">✔️</mark></td></tr><tr><td>Key Field</td><td>This is the field API name for mapping data which has been retrieved through the DataSource.</td><td><mark style="color:red;">✔️</mark></td></tr><tr><td>Parent Field Parameters</td><td>Represents fields from the Parent object which are to be passed as parameters.</td><td></td></tr><tr><td>Lookup Field Parameters</td><td>Represents fields from the Lookup object which are to be passed as parameters.</td><td></td></tr><tr><td>Active</td><td>Turns the DataSource on or off. It must be active to be used.</td><td><mark style="color:red;">✔️</mark></td></tr></tbody></table>

### Creating an Apex Class

Before you can use an external data source, you must write an Apex Class. Implement the `SBLD.DataSourceService.Fetchable` interface provided by the package by implementing it in the Apex Class you want to write.

Classes implementing `SBLD.DataSourceService.Fetchable` must implement the `execute()` method.

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

```apex
global with sharing class DataSourceServiceMock implements SBLD.DataSourceService.Fetchable {
    /***
     * @description SBLD.DataSourceService.Fetchable execute() definition
     * @param param SBLD.DataSourceService.Parameter parameter type 
     *              set by the 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  type String, choose between 'Parent' 
         *          and 'Lookup' (case insensitive)
         *  @return List<SObject>
         **/
        SObject parentRecord = null;
        List<SObject> lookupRecords = new List<SObject>();
        // Gets Parent-specific parameters.. 
        if(param.gets('parent')<>null && !param.gets('parent').isEmpty()) {
            parentRecord = param.gets('parent')[0];
        }
        // Gets Lookup-specific parameters..
        if(param.gets('lookup')<>null && !param.gets('lookup').isEmpty()) {
            listLookupParameters = param.gets('lookup');
        }
        /**
         * On success, sets the result to send to SmallBuilder.
         **/
        for(SObject sobj : lookupRecords) {
            /**
             * Similarly to Internal DataSources, the Action maps a 
             * value from a DataSource to a Lookup or Line-item field. 
             **/
            SBLD.DataSourceServiceAction action = new SBLD.DataSourceServiceAction();
            /** 
             * 1. Set the value of the key from the External DataSource, 
             *    to map to the Lookup or Line-item records.
             **/
            action.setKeyValue(sobj.get('Id')); // e.g. Product Code
            /** 
             * 2. Maps values imported from the External DataSource 
             *    to Lookup or Line-item fields.
             **/
            Map<String, Object> mapPopulatedField = sobj.getPopulatedFieldsAsMap();
            for(String fieldName : mapPopulatedField.keySet()) {
                action.putSourceToTargetField(mapPopulatedField.get(fieldName), fieldName);
            }
            // 3. Add an Action to DataSourceService.Result.
            result.addAction(action);
        }
        return result;
    }
}
```

{% endcode %}

You can get information from the Parent or Lookup objects through the `gets()` method in `SBLD.DataSourceService.Parameter`.

{% code lineNumbers="true" %}

```apex
global SBLD.DataSourceService.Result execute(SBLD.DataSourceService.Parameter param) {
    SObject parentRecord = null;
    List<SObject> lookupRecords = new List<SObject>();
    // Gets Parent-specific parameters.
    if(param.gets('parent')<>null && !param.gets('parent').isEmpty()) {
        parentRecord = param.gets('parent')[0];
    }
    // Gets Lookup-specific parameters.
    if(param.gets('lookup')<>null && !param.gets('lookup').isEmpty()) {
        listLookupParameters = param.gets('lookup');
    }
    ...
}
```

{% endcode %}

To pass the result to the Line-Item Configurator, we use the class below.

### **SBLD.DataSourceServiceAction Class**

Specifies an Action for each line in the target (Lookup or Line-item). An Action is an operation that maps a DataSource value to a Lookup or Line-item field.

* **setKeyValue(Object keyValue)**\
  Sets the Key value to find the target record for the Lookup or Line-item.
* **putSourceToTargetField(Object sourceValue, String targetField)**\
  Assigns a data source value to a Lookup or Line-item field.

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

Adds the mapped Action to the return value.

* **addAction(SBLD.DataSourceServiceAction action)**\
  Adds an Action to the `SBLD.DataSourceService.Result` instance.

{% code lineNumbers="true" %}

```apex
// Get data from External Server
HttpRequest request = new HttpRequest();
Request.setMethod(‘POST’);
...
HttpResponse response = new Http().send(request);

List<Object > listResults = (List < Object>)JSON.deserializeUntyped(Response.getBody());

/*Response Body:
[ { itemCode: ‘000001’,  inventory: 3 }, { itemCode: ‘000002’,  inventory: 0 },…  ]

Lookup Record:
[ { Id: ‘XXXXXX1’, ProductCode: ‘000001’, ‘Inventory__c’: null }... ]
*/


...

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();
    /**
     *  A value that matches the Key field in the DataSource
     *  External Server Key: itemCode,
     *  Lookup Key: ProductCode
     **/
    action.setKeyValue(mapResponse.get('Id')); // e.g. Product Code
    // Populating a Lookup or Line-item field with a value from the External DataSource
    action.putSourceToTargetField(mapResponse.get('inventory'), 'Inventory__c');
    // Add an Action to SBLD.DataSourceService.Result.
    result.addAction(action);
}
return result;
```

{% endcode %}

### Example

Under construction! [Contact us](https://www.smallbuilder.com/contact-us) if you need further help.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.smallbuilder.com/smallbuilder-line-items/setup/datasource/external.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
