Capabilities
A capability can be defined with attributes in a data shape and services in a thing shape in a way that allows it to be applied to multiple types of resources. For example, an "Ownable" asset resource has the "Ownable" capability of being associated to an owner. A resource can have multiple capabilities as well.
To apply a capability to a resource, the resource provider implements a service provider thing shape with services of the capability. The attributes in the capability data shape are included in the resource data shape. The capability data shape should be named in a similar convention based on the capability service provider thing shape. For example, an "Owner" attribute defined in PTC.Capability. OwnableDataShape will be included in PTC.Resource.Asset.ThingworxAssetDataShape when PTC.Resource.Asset. ThingworxAssetResourceProvider implements PTC.Capability.OwnableServiceProvider thing shape. This "Owner" attribute, like other attributes of an asset resource, will have a mapping created by default in the configuration table.
The service defined in a capability service provider thing shape should always take an InfoTable parameter named "objects" that represents the resources for the service to be invoked on. If a service is implemented on a thing shape, it should be agnostic towards the resource and be overridable on an implementing resource provider in case it requires a specific implementation.
Relationship
Relationships between resources can be modeled as capabilities. One capability data shape can be defined to bring a foreign key attribute to the resource on one side of the relationship. Another capability data shape can be defined to bring an InfoTable attribute to the resource on the other side of the relationship such that it could be expanded to embed the resources with the foreign key. Each capability service provider thing shape has a getter service to allow navigating the relationship from either side.
For example, the "Owner" attribute is a foreign key attribute on an asset resource when an asset resource provider implements the "Ownable" capability service provider thing shape described previously. In addition, a "GetOwner" service can be defined on the "Ownable" service provider thing shape to get the referenced "owner" resource. However, an "Owning" capability service provider thing shape can be defined to provide a "GetOwnables" service that can navigate from an "owning" resource to its referencing "ownable" resources as well. In addition, an "Ownables" attribute is defined in the "Owning" capability data shape to be expanded on an "owning" resource as an embedded InfoTable of its "ownable" resources. However, this attribute does not need to be mapped to anything on the resource provider.
The getter service can be implemented on each thing shape to navigate such a relationship either within one system or across different systems by passing the foreign key attribute name and the other service provider thing shape name to a generic service in ResourceManager. For example, "GetOwner" service on "Ownable" thing shape would be:
var params = {
        objects: objects /* an ownable resource */,
        relationship: "PTC.Capability.OwningServiceProvider" /* ThingShape name */,
        foreignKey: "Owner" /* foreign key name */
    };

    // Get the owner resource
    var result = Things["PTC.Resource.ResourceManager"].NavigateForeignKeyRelationship(params);
Similarly, "GetOwnables" service on "Owning" thing shape would be:
var params = {
        objects: objects /* an owning resource */,
        relationship: "PTC.Capability.OwnableServiceProvider" /* ThingShape name */,
        foreignKey: "Owner" /* foreign key name */
    };

    // Get the ownable resources
    var result = Things["PTC.Resource.ResourceManager"].NavigateForeignKeyRelationship(params);