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);