# External data sources

**External data sources should be used when you want to retrieve data from an external server and present it alongside data from a standard or custom Salesforce object. Since the datasource is accessed using a user-defined Apex class, you can retrieve data more flexibly compared to an internal datasource.**

For example, if you want to retrieve real-time inventory numbers from an external system and display them on-screen alongside your product information, you can write REST API code in an Apex Class to do this.

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

  Describes the properties to be configured when using an external datasource.
* [**Creating an Apex class**](#creating-an-apex-class)

  Before you can use an external datasource, you must write an Apex class. Your class must implement the `SBLD.DataSourceService.Fetchable` interface provided in the package.
* [**Example**](#example)

***

### Properties

There are several properties to be configured when using an external datasource.

<figure><img src="https://3800415611-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNuSjRiJMvVhtdzNDzWBi%2Fuploads%2FYhdU8J6ujqlR0sKgmPTF%2Fimage%20(45).png?alt=media&#x26;token=a5993c2a-f58f-4a65-864a-1af9a5359576" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3800415611-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNuSjRiJMvVhtdzNDzWBi%2Fuploads%2Fw8Dod6fSuRNXWYZuf5V1%2Fimage%20(46).png?alt=media&#x26;token=855df808-ef09-4e7d-91bb-8d7554dab474" alt=""><figcaption><p>Apex class for an external datasource</p></figcaption></figure>

<figure><img src="https://3800415611-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNuSjRiJMvVhtdzNDzWBi%2Fuploads%2FIQ52HRih9V3UPf9znXFP%2Fimage%20(47).png?alt=media&#x26;token=04aa16aa-4e34-4285-8da8-b488a0d1db41" alt=""><figcaption><p>Flow for an external datasource</p></figcaption></figure>

<table><thead><tr><th width="163">Field name or area</th><th width="385">Description</th><th>Req.</th></tr></thead><tbody><tr><td>Select the type of external connection.</td><td><p>There are two ways to connect to external datasources.</p><ul><li>Apex - use an Apex class that <code>implements</code> the <code>SBLD.DataSourceService.Fetchable</code> interface.</li><li>Flow - use an automatically executing Flow.</li></ul></td><td><mark style="color:red;">✔️</mark></td></tr><tr><td>Enable</td><td>Enables the datasource. A disabled datasource will not be available when building custom lists.</td><td></td></tr><tr><td>Description</td><td>Provide a description of your datasource.</td><td></td></tr><tr><td>Key Field</td><td>Specifies which fields from the List object should be matched with fields from the datasource.</td><td><mark style="color:red;">✔️</mark></td></tr><tr><td>Parameters</td><td>If your datasource needs to be passed values from fields in the List object, select those fields here.</td><td></td></tr><tr><td>Input Variable</td><td>Select the parameter variables to pass to the Flow. If no parameters are required, leave unchecked.<br>💡 The displayed options are those marked "Available for input" in the Flow.<br><img src="https://3800415611-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNuSjRiJMvVhtdzNDzWBi%2Fuploads%2FUMyj3knAvSWQpzC25Puc%2Fimage%20(48).png?alt=media&#x26;token=2a3a4465-7de3-4b55-b44c-03e44488ef64" alt=""></td><td></td></tr><tr><td>Output Variable</td><td>Select the variables to receive the results from the Flow.<br>💡 The displayed options are those marked "Available for output" in the Flow.<br><img src="https://3800415611-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNuSjRiJMvVhtdzNDzWBi%2Fuploads%2FFB23BHHQA2pluJ2LtORt%2Fimage%20(49).png?alt=media&#x26;token=54be4e9e-6ed7-46fb-8766-755334e8bdf3" alt=""></td><td><mark style="color:red;">✔️</mark></td></tr></tbody></table>

### Creating an Apex class

Before you can use an external datasource, you must write an Apex class. Your class must implement the `SBLD.DataSourceService.Fetchable` interface provided in the package.

You must also implement the `execute()` method in your class.

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

```java
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 results = new SBLD.DataSourceService.Result();
        /**
         *  @method DataSourceService.Parameter gets()
         *  @param  String Parent, choose from Lookups (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 back to SmallBuilder.
         **/
        for(SObject sobj : lookupRecords) {
            /**
             * Similarly to internal datasources, the Action maps a 
             * value from a datasource to a field in the List's underlying object.
             **/
            SBLD.DataSourceServiceAction action = new SBLD.DataSourceServiceAction();
            // 1. Set the value of the key from the External datasource
            action.setKeyValue(sobj.get('Id')); // Product Code
            // 2. Maps fields from the external datasource to fields in the List's underlying object.
            Map<String, Object> mapPopulatedField = sobj.getPopulatedFieldsAsMap();
            for(String fieldName : mapPopulatedField.keySet()) {
                action.putSourceToTargetField(mapPopulatedField.get(fieldName), fieldName);
            }
            // 3. Add an Action to DataSourceService.Result.
            results.addAction(action);
        }
        return results;
    }
}
```

{% 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
...
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')); // Product Code
    // Populating a Lookup or Line-item field with a value from the External DataSoure
    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 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-lists/setup/datasource-setup/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.
