FDC3 Compliance

Overview

FDC3 aims at developing specific protocols and classifications in order to advance the ability of desktop apps in financial workflows to interoperate in a plug-and-play fashion without prior bilateral agreements.

FDC3 for io.Connect Browser

This guide explains how to run an FDC3 compliant app in an io.Connect Browser project. For detailed information on the FDC3 API itself, see the FDC3 documentation.

⚠️ Note that the examples in the following sections follow the FDC3 2.0 standard.

Initialization

The @interopio/fdc3 library is the io.Connect implementation of the FDC3 standards. To use the @interopio/fdc3 library in your project, install the package:

npm install @interopio/fdc3

Reference the library in your app:

import "@interopio/fdc3";

You can also reference it as a script from UNPKG:

<script src="https://unpkg.com/@interopio/fdc3@latest/dist/fdc3.umd.js"></script>

Now the FDC3 API will be available as an fdc3 object attached to the global window object:

const contextType = "Contact";
const handler = context => console.log(`Context: ${JSON.stringify(context)}`);

fdc3.addContextListener(contextType, handler);

Intents

The FDC3 Intents concept serves the purpose of enabling the creation of cross-app workflows on the desktop. An app declares an Intent through configuration or at runtime. An Intent specifies what action the app can execute and what data structure it can work with.

Intents can be defined using the intents key of the app definition objects in the Main app configuration or in the app definitions provided by a remote source (both io.Connect and FDC3 app configuration files). Intents can be configured under the intents top-level key of the app definition:

The following example demonstrates how to define an Intent in the app definition object in the Main app configuration:

import IOBrowserPlatform from "@interopio/browser-platform";

const config = {
    licenseKey: "my-license-key",
    applications: {
        local: [
            {
                name: "Instrument Chart",
                details: {
                    url: "http://localhost:4242/chart"
                },
                // Intent definitions.
                intents: [
                    {
                        name: "ShowChart",
                        displayName: "BBG Instrument Chart",
                        contexts: ["Instrument"]
                    }
                ]
            }
        ]
    }
};

const { io } = await IOBrowserPlatform(config);
Property Type Description
name string Required. The name of the Intent.
displayName string The display name of the Intent. Can be used in context menus, etc., to visualize the Intent.
contexts string[] The type of predefined data structures with which the app can work (see FDC3 Contexts).

For more details on defining apps, see the Capabilities > App Management > App Definitions section.

For more details on using Intents, see the FDC3 Intents API.

The Intents Resolver UI app allows users to choose an app for handling a raised Intent:

Intents Resolver

For more details on how to enable or disable the Intents Resolver UI, or on how to create your own custom Intents Resolver App, see the Capabilities > Intents > Intents Resolver section.

Channels

An FDC3 Channel is a named context object that an app can join in order to share and update context data and also be alerted when the context data changes. By specification, Channels can be either well-known system Channels or Channels created by apps. On a UI level, Channels can be represented by colors and names.

To define system Channels, use the Main app configuration. Use the following configuration to create io.Connect Channels mapped to the default FDC3 Channels:

import IOBrowserPlatform from "@interopio/browser-platform";

const channels = {
    definitions: [
        {
            "name": "Red",
            "meta": {
                "color": "red",
                "fdc3": {
                    "id": "fdc3.channel.1",
                    "displayMetadata": {
                      "name": "Channel 1",
                      "glyph": "1"
                    }
                }
            }
        },
        {
            "name": "Orange",
            "meta": {
                "color": "#fa5a28",
                "fdc3": {
                    "id": "fdc3.channel.2",
                    "displayMetadata": {
                        "name": "Channel 2",
                        "glyph": "2"
                    }
                }
            }
        },
        {
            "name": "Yellow",
            "meta": {
                "color": "#FFE733",
                "fdc3": {
                    "id": "fdc3.channel.3",
                    "displayMetadata": {
                        "name": "Channel 3",
                        "glyph": "3"
                    }
                }
            }
        },
        {
            "name": "Green",
            "meta": {
                "color": "green",
                "fdc3": {
                    "id": "fdc3.channel.4",
                    "displayMetadata": {
                        "name": "Channel 4",
                        "glyph": "4"
                    }
                }
            }
        },
        {
            "name": "Cyan",
            "meta": {
                "color": "#80f3ff",
                "fdc3": {
                    "id": "fdc3.channel.5",
                    "displayMetadata": {
                        "name": "Channel 5",
                        "glyph": "5"
                    }
                }
            }
        }
        {
            "name": "Blue",
            "meta": {
                "fdc3": {
                    "id": "fdc3.channel.6",
                    "displayMetadata": {
                        "name":"Channel 6",
                        "glyph": "6"
                    }
                }
            }
        },
        {
            "name": "Magenta",
            "meta": {
                "color": "#cc338b",
                "fdc3":   {
                    "id": "fdc3.channel.7",
                    "displayMetadata": {
                        "name": "Channel 7",
                        "glyph": "7"
                    }
                }
            }
        },
        {
            "name": "Purple",
            "meta": {
                "color": "#c873ff",
                "fdc3": {
                    "id": "fdc3.channel.8",
                    "displayMetadata": {
                        "name": "Channel 8",
                        "glyph": "8"
                    }
                }
            }
        }
    ]
};

const config = {
    licenseKey: "my-license-key",
    channels
};

const { io } = await IOBrowserPlatform(config);

Any custom Channel you define, must be mapped to an FDC3 Channel if you want to use it as such.

For more details on defining Channels, see the Capabilities > Data Sharing > Channels section.

For a sample Channel Selector widget implementation, see the Capabilities > Data Sharing > Channels > Channel Selector UI section. The example uses internally the io.Connect Browser Channels API and not the FDC3 Channels API.

For more details on using Channels, see the FDC3 Channels API.

App Directory

The goal of the FDC3 App Directory REST service is to provide trusted identity for desktop apps. App definitions are provided by one or more App Directory REST services where user entitlements and security can also be handled.

For more details on the FDC3 app configuration standards, see the FDC3 Application schema.

To configure io.Connect Browser to retrieve app definitions from remote app stores, use the remote property of the applications object in the Main app configuration:

import IOBrowserPlatform from "@interopio/browser-platform";

const config = {
    licenseKey: "my-license-key",
    applications: {
        remote: {
            url: "http://localhost:3001/v2/apps/",
            pollingInterval: 1000,
            requestTimeout: 5000
        }
    }
};

const { io } = await IOBrowserPlatform(config);

The remote object has the following properties:

Property Type Description
url string Required. The URL of the remote source of app definitions. The remote source must follow the FDC3 App Directory standard. The provided apps must be of type AppManager.Definition or FDC3Definition.
pollingInterval number The polling interval for fetching app definitions from the remote source in milliseconds. If not provided, the platform will fetch the app definitions only once on startup. Defaults to 3000.
requestTimeout number The request timeout for fetching app definitions from the remote source in milliseconds. Defaults to 3000.
customHeaders object Request headers in the form of name/value pairs that will be appended to every request.

⚠️ Note that any app can connect to remote sources and not only the Main app. The app definitions from all remote sources are then merged by the Main app. The remote sources can supply both io.Connect and FDC3 app definitions. The only requirement for an FDC3 app definition to be usable in io.Connect Browser is to have a valid details.url or a url top-level property in its manifest JSON string property.

Alternatively, you can supply the app definitions locally to the Main app by using the local property of the applications object.

According to the FDC3 App Directory specifications, the remote store must return app definitions in the following response shape:

{
    "applications": [
        // List of app definition objects.
        {}, {}
    ]
}

For a reference implementation of the FDC3 App Directory, see the Node.js REST Config Example on GitHub.

For more details on defining apps, see the Capabilities > App Management > App Definitions section.

For more details on using App Directory, see the FDC3 App Directory documentation.

Demo

Example of the broadcast(), addContextListener(), findIntentsByContext() and raiseIntent() API calls implemented by @interopio/fdc3 are available in this demo.

The demo consists of a Chart and a Blotter app. Searching and selecting a ticker in the Chart app adds it to the Blotter app as long as the two apps are on the same Channel (use the Channel Selector widget to navigate between Channels):

FDC3 Demo

Right-clicking on an instrument in the Blotter opens a context menu with the Intents that can be raised for the instrument. If the Chart app is running, it will update its context, and if there are no instances of the Chart app running, a new instance with the given context will be started.

Use the code of the demo as a reference when adapting your own apps.

Extension

The demo project also contains a Chrome extension that auto injects @interopio/fdc3 in all web pages. It spares you the need to reference the library in all your projects and redeploy them or when integrating with third-party closed source apps.

To install the extension, follow the instructions in the README file.