App Bridging

Overview

A Holochain application createds a coherent independent unit of agreement between a distributed set of nodes for playing together according to a set of rules as defined by that application's DNA.  Such independent units must be able to compose with other such units.  In the Holochain world, we call this composing "bridging," because the composition happens at the nodal point of an Agent who bridges two such spaces by virtue of their agency.  In other words it's not that "applications" in some abstract way connect to other applications via an API, but rather, that an agent by having an identity in two applications can make calls into those applications that cause a flow of information between them.

Applications, can be designed, of course to expect this kind of bridging to occur.  For example, an application might be designed to make use of a distributed indexing service provided by another application, and therefore, if available send all new entries to that bridged app for indexing.

Establishing a Bridge

Establishing a bridge happens once, i.e. an application gets bridged to another application as a result of an agent declaring the brigde, and when this happens the bridging gets registered on both "sides" of the bridge.  In all cases the bridge is considered to be uni-directional where one side will be the "caller" i.e. issue bridge() calls, and the other side will be be the "callee", i.e. receive such calls. You must declare the functions you want to expose to other applications by adding an array of the function names to your DNA.

When the bridge gets established, this triggers a call to bridgeGenesis in both apps.  This provides a time when the apps can do any validation necessary, i.e. membrane management, for example, and even reject the bridging.

In testing, you can establishing bridges by creating a bridge_specs.json file.  This file consists of an array of paths that point to the source code of other applications.  An object in the array has this format:

 {
        Path:                    string // path to the app to bridge to/from
        Side:                    int    // what side of the bridge the dev app is (Bridge.Caller or Bridge.Callee)
        BridgeGenesisCallerData: string // genesis data for the caller side
        BridgeGenesisCalleeData: string // genesis data for the callee side
        Port:                    string // only used if side == BridgeCallee
        BridgeZome:              string // only used if side == BridgeCaller
}

This file should live in the main directory of your application.  You may also want to establish bridging for each role in a scenario when doing scenario testing.  To do so you would add a role specific specs file into the scenario directory of the form: _<role>_bridge_specs.json

The hcadmin bridge command allows you to establish a bridge in a non-test app.

Using Bridges

bridge provides access to calling a function in a bridged application.

An application can inspect which bridges have been created by using the getBridges() function.  This may be necessary if the existence of a bridge is optional.

Future Developments

Currently we make a distinction in the DNA between "BridgeFuncs" and other functions of the API.  The BridgeFuncs are only accessible to a caller that got registered with the callee when the bridge was established.  The "regular" functions exposed to the UI are available via localhost://fn/, whereas the bridge() call makes use of connecting through localhost://bridge/ and passes an authentication token received during the bridge establishment.

In the future we will be generalizing this, and creating a set of capabilities that app developers can assign to the functions they add to their apps.  Some function calls will then require a capability token to run.