-
Notifications
You must be signed in to change notification settings - Fork 99
Description
In order to support having a dependency on another bundle, where the exact bundle is not specified but you know what you need from the bundle, we need to define what is a bundle's interface.
Similar to the Go programming language, the interface is defined by the bundle that would use it, not the bundle that implements it. So a bundle doesn't say "I implement the mysql interface", instead a bundle that needs mysql would define the interface it requires and any bundle could match.
For example, a wordpress bundle that just needs a mysql database of any type could define the dependency as follows:
dependencies:
requires:
- name: mysql
reference: getporter/mysql:v0.1.1
interfaceDocument: # bundle.json document embedded
Reference another bundle and use it as an interface
dependencies:
requires:
- name: mysql
reference: getporter/mysql:v0.1.1
interfaceReference: getporter/mysql:v0.1.1
Any bundle that outputs a string parameter named connectionString could then be used for that dependency.
Just going by name and type is a bit difficult however. From experience I know that getting bundle authors to all use the same names for anything is a challenge. Since output supports jsonschema, we could also have interfaces be based on a set of matching characteristics. So whatever is defined on the output, must be matched on the outputs on the candidate bundle.
One way to help bundle authors use consistent naming that would support dependencies matching the correct characteristics would be to provide a non-normative spec section just for interfaces that people are using. In the example below, the output would need its $id field to be a well-known string (a URI in this case but it doesn't have to be) that indicates the intent of the output. In this case a mysql connection string.
dependencies:
requires:
- name: mysql
interface:
outputs:
- $id: "https://cnab.io/interfaces/mysql#connectionString"
type: string
Note that bundle dependencies cannot alter the exposed interface of the parent bundle. The parent bundle is responsible for defining any parameters/credentials/outputs necessary to use the dependency and then manage wiring up those values so that they are exposed.
The question is then
- What can be used in a bundle interface? Outputs, parameters, credentials, custom actions, ... anything else?
- How do we decide if it's a match? i.e. are we comparing against all possible fields on those above definitions or only a subset?
- Do we want to provide guidance on how best to define an interface in a parent bundle and how other bundles can make themselves more likely to match?