Skip to content

Reading Data

Define the Data Objects you want to get from your system.

You will need to provide the specific data objects you want to share to the App Xchange cache. This structure is in the form of a C# model.

Key considerations

  • Each data object identified for sharing in your Connector Strategy will be represented as separate C# models.
  • These models will be stored in your repository and referenced in your code.
  • These models are converted to json and stored by App Xchange so they can enable future Integrations using your Connector.

Get your Data Using a Data Reader.

The App Xchange Data Reader is how you get the data from your system that you designate into the App Xchange Cache.

Key considerations

  • The data reader is defined through code you write (in C#) and is included in your Connector codebase (in your Connector Github Repository).
  • The CLI Tool will help you generate and structure much of the code you need.
  • You will need to know the properties of your data as represented in your C# models.
  • Before you begin, consider using an incremental data reader if a full data read is impractical.

The App Xchange Connector Cache.

The Xchange Cache keeps a copy of your data for the purpose of detecting changes and triggering Flows.

Key considerations

  • The cache is a Cosmos DB document storage and it is the source of truth for your Xchange Connector.
  • The cache is updated based on a variety of factors, but most often based on a polling of changes.
  • The cache will persist until it is purged.

Create an initial placeholder data object

In the directory your Connector’s C# project resides use this CLI command to begin:

This directory is named Connector by default

Example CLI command:

xchange data-object new --module-id app-1 --name Employees

About this command:

data-object new This command will instantiate a new data object. The following are options for that command:

module-id (required) A module allows for the grouping of various functionality in your Connector code. In this specific instance, we’re using a generic default group called: app-1.

connector-path This defines the path to which your Connector’s C# project resides within the repository. Defaults to the current directory.

object-name (required) In this instance we are using Employees as a placeholder for your object’s name.

Example result: This command will create a new directory in your connector project. Within the App/v1 directory there is a file named Employees (Where Employees is the object name provided).

It will also create the following:

EmployeesDataObject EmployeesDataReader

EmployeesDataObject will also be added to its corresponding config and service definitions for this module. These files can be found at:

Connector / App / v1 / AppV1CacheWriterConfig.cs
Connector / App / v1 / AppV1CacheWriterServiceDefinition.cs


Add Properties to the initial placeholder data object

Within the codebase, go to the initial placeholder data object you have created within App / v1 /EmployeesDataObject. Open EmployeesDataObject.cs so you can add properties to that data object.

The data properties you add should match those provided by your API. Refer to Connectivity FAQ to have a better understanding on connector's scope.

For more guidance on how to add properties to your data objects follow our object schema guide.


Write data to the App Xchange cache

The App Xchange cache is the source of truth for your Xchange Connector. The data in the cache is what will be shared to other systems. In this next step we'll build what is required to write the shareable data to the Xchange cache. Cache writing is performed automatically by the Xchange platform, however, you will need to use a Data Reader in order to get the data from your system into the Xchange platform.

Modify the Data Reader template for your new object

Within the repository, go to the initial placeholder data object you have created within App / v1 / EmployeesDataObject. Open EmployeesDataReader.cs in order to modify the GetTypedDataAsync method so that it will return a collection of data as EmployeesDataObject(s).

In order to validate that everything is functioning properly, the sample data you return in your initial implementation should be dummy/test data.

Modify data reader to use your client

If you haven't done the initial setup for your client, please follow the instructions in how to build a client for your connector.

Your data reader currently is using the hard coded EmployeesDataObject you provided. In this step we’ll update the data reader so that it pulls data using your client instead.

We will start by modifying the EmployeesDataReader.cs. Here is the path to that file: Connector / App / v1 / Employees/EmployeesDataReader.cs*

Modify the EmployeesDataReader.cs file in the following ways:

Add ApiClient client to the constructor so that it can be used for GetDataTypeAsync method.

Example of a client injection into EmployeesDataReader
public EmployeesDataReader(
        ILogger<EmployeesDataReader> logger,
        IHostContext hostContext,
        ApiClient apiClient)
    {
        _logger = logger;
        _hostContext = hostContext;
        _apiClient = apiClient;
    }

Change the GetDataTypeAsync method so that it can be used to get actual data from your system.

Example of a GetDataTypeAsync implementation
GetDataTypeAsync.cs
public override async IAsyncEnumerable<EmployeesDataObject> GetTypedDataAsync(DataObjectCacheWriteArguments ? dataObjectRunArguments, [EnumeratorCancellation] CancellationToken cancellationToken)
{
    ApiResponse<EmployeesDataObject[]> response;
    try
    {
        response = await _apiClient.GetEmployees(cancellationToken) // (1)
            .ConfigureAwait(false);
    }
    catch (ApiException exception)
    {
        if (exception.InnerException != null)
        {
            _logger.LogError(exception.InnerException, "Unexpected Exception: {Message}", exception.InnerException.Message);
            _logger.LogError("API response: {Message}", exception.Message);
            throw;
        }
        if (exception.StatusCode is >= 200 and <= 299)
            yield break;
        throw;
    }

    var result = response.Result;

    if (result == null) // (2)
    {
        _logger.LogWarning("No data returned from API");
        yield break;
    }

    foreach (var item in result)
    {
        var resource = new EmployeesDataObject // (3)
        {
            EmployeeId = item.EmployeeId,
            FirstName = item.FirstName,
            LastName = item.LastName,
            Active = item.Active
        };
        yield return resource; // (4)
    }
}
  1. Make a call to your API to retrieve the objects from your system.
  2. Verify the API call retrieved the objects from your system.
  3. Create new EmployeesDataObject and map retrieved objects properties to it.
  4. Return new EmployeesDataObject to Xchange cache.

Let’s test it out!

Now that you've built a data object and a cache writer, we can test to ensure that everything is behaving like it should.

To test your connector locally, check out our guide for local testing here. Otherwise, continue to Creating Actions