Entity Relationships


Defining entity relationships

The Platform allows you to define relationships between entities much like you would define relationships between tables in a relational database yet it provides additional aspects of Object Oriented Design.

The following types seen below are key association types and the meaning of their relationships.

Platform Type Description Cardinality UML Type
common:consists_of The source entity contains the destination entities. one to many Composition
common:aggregates_of The source entity may have destination entity associated with it. one to many Aggregation
common:relates_to The source entity may relate to the destination entity. many to many Association
common:is_a The destination entity offers a specific qualification for the source entity. one to one Composition
common:has The destination entity may be associated with the source entity. one to many Aggregation
common:uses The destination entity depends on the source entity. many to one Composition


Association declarations VS derivations

The defacto rule for using association declarations VS association derivations is…

  • Use Association Declarations If…
    • OTLP payload will always include both entities realted to each other
  • Use Association Derivations If…
    • OTLP payload for the entities related to each other will be sent at different times

Our example UgottaRide solution, uses both association declarations and association derivations which we will discuss in more detail in the sections below.


Add association types for entities

You must manually add your association type(s) to your entity definitions regardless of which type of association you decide to use. The rule of thumb is to add your association types within the parent entity definition, not the child entity. In the example below (lines 40 - 44) we see that the rider entity is declaring a common:has relationship to the ride entity, which means that a single rider can have many rides (over time) associated with the rider.

/fsoc_projects/my_tenant/ugottaride/objects/model/entities/rider.json

image


  Now add the association types in each of the following entity json files.

/fsoc_projects/my_tenant/ugottaride/objects/model/entities/rider.json

    "associationTypes": {
        "common:has": [            
            "ugottaride:ride"
        ]
    }


/fsoc_projects/my_tenant/ugottaride/objects/model/entities/ride.json

    "associationTypes": {
        "common:has": [            
            "ugottaride:ride_assign"
        ]
    }


/fsoc_projects/my_tenant/ugottaride/objects/model/entities/driver.json

    "associationTypes": {
        "common:has": [            
            "ugottaride:ride_assign"
        ]
    }


/fsoc_projects/my_tenant/ugottaride/objects/model/entities/vehicle.json

    "associationTypes": {
        "common:has": [            
            "ugottaride:ride_assign"
        ]
    }


  Dev Tip While our example UgottaRide solution has only one association defined in the parent entities, the Platform supports associations in a given parent to multiple children with multiple association types as seen in the example below from another solution.

    "associationTypes": {
        "common:aggregates_of": [ 
            "saplegacy:system_instance", 
            "saplegacy:backend", 
            "saplegacy:business_transaction" 
        ],
        "common:has": [ 
            "saplegacy:system_database_status", 
            "saplegacy:system_logs_errors_status",  
            "saplegacy:system_server_status",
            "saplegacy:system_workprocs_users_status"
         ]
    }


  You can get more details about the json structure of entity definitions, including the supported relationship types here:


Add an association declaration

The Platform allows you to model your solution from the perspective of a real world context. In a real world ride share service context, we know that when a rider makes a request for a new ride, the details of the requested ride will be sent in the ride request, but that the rider had previously created an account with the ride share service, so there would be no need to send all the details for the rider in the same request, just enough data to uniquely identify the rider.

In the real world we would use an association derivation for this relationship. However, we are going to create an association declaration between the rider and the ride and then send all the details of the rider and the ride within the same request (e.g. the same OTLP payload), so that you gain an understanding of how an association declarations works.

image

  Use the following commands to add a new association declaration for the rider entity.

fsoc command to add an association declaration for an entity in your solution.
Command Format: fsoc solution extend --add-associationDeclarations <entity_name>
Command Help: fsoc solution extend -h

Windows Example Commands:

cd C:\fsoc_projects\my_tenant\ugottaride

fsoc solution extend --add-associationDeclarations rider

Unix-Mac Example Commands:

cd /fsoc_projects/my_tenant/ugottaride

fsoc solution extend --add-associationDeclarations rider

What did these fsoc commands do?

  • Created new subdirectories under /fsoc_projects/my_tenant/ugottaride/objects/model
  • Created five entity definition files under /fsoc_projects/my_tenant/ugottaride/objects/model/association-declarations
    • rider-associationDeclarations.json
  • Updated the manifest.json file to reference the directory and files it created

/fsoc_projects/my_tenant/ugottaride/objects/model/association-declarations/rider-associationDeclarations.json

[
    {
        "namespace": {
            "name": "ugottaride",
            "version": 1
        },
        "kind": "associationDeclaration",
         "name": "ugottaride_rider_to_ride_relationship",
        "displayName": "Declared Relationship between rider and ride",
        "scopeFilter": "true",
        "fromType": "ugottaride:rider",
        "toType": "ugottaride:ride",
        "associationType": "common:has"
    }
]


Add association derivations

Currently, there is no fsoc command that will generate association derivations for you. You must define them manually, however, we have some good examples for association derivations in our example UgottaRide example solution.

  Dev Tip Remember, we must use association derivations to establish a relationship between two entities whos OTLP payloads are sent at different times.

Below are the “golden rules” when creating / using association derivations:

  • The child entity must have an additional attribute or attributes that match the primary key attribute(s) of the parent that is already persisted
  • Because the entities will be ingested independently, the Platform needs to be able to establish the association from the perspective of either of the entities involved in it. Therefore, you must have two association derivation definitions, one for each entity involved in the relationship.
  • The primary key attribute(s) of the parent must be sent as attributes in the child resource attributes. This creates the link between the child and the parent within the single payload.

primary key = only the required attribute(s) that make an entity instance unique


We will go into more detail in the section where we create mock MELT data for the payloads, whereas here we are focusing on the association derivation definition.

Let’s look at the association derivation definition between the ride and ride_assign entities. In the real world, a rider requests a ride, and then, hopefully soon afterward, a driver then confirms the request, which triggers the creation of the ride_assign that links the driver and the vehicle to the ride.

In this real world context, we know that the payload for the ride_assign will always be ingested at a different time than the payload for the ride.

image

In the first example below, we have used one JSON file to add two association derivation definitions, one from ride to ride_assign and one from ride_assign to ride.


  Dev Tip It is best practice to add your solution name as a prefix to the name of both association declarations and association derivations (as seen in the examples below).


  Now go ahead and create the association derivations for three of our entities.


/fsoc_projects/my_tenant/ugottaride/objects/model/association-derivations/ride_assign_ride-associationDerivations.json

[
    {
        "namespace": {
            "name": "ugottaride",
            "version": 1
        },
        "kind": "associationDerivation",
        "name": "ugottaride_ride_to_ride_assign_association",
        "displayName": "Derived Relationship between ride and ride_assign",
        "associationType": "common:has",
        "fromType": "ugottaride:ride",
        "toType": "ugottaride:ride_assign",        
        "scopeFilter": "true",
        "mappings": {
            "attributes": {
                "rideid": "this.attributes.'rideid'.value"                
            }
        }
    },    
    {
        "namespace": {
            "name": "ugottaride",
            "version": 1
        },
        "kind": "associationDerivation",
        "name": "ugottaride_ride_assign_to_ride_association",
        "displayName": "Derived Relationship between ride_assign and ride",
        "associationType": "common:has",
        "fromType": "ugottaride:ride_assign",
        "toType": "ugottaride:ride",        
        "scopeFilter": "true",
        "mappings": {
            "attributes": {
                "rideid": "this.attributes.'rideid'.value"                
            }
        }
    }
]


/fsoc_projects/my_tenant/ugottaride/objects/model/association-derivations/ride_assign_driver-associationDerivations.json

[
    {
        "namespace": {
            "name": "ugottaride",
            "version": 1
        },
        "kind": "associationDerivation",
        "name": "ugottaride_driver_to_ride_assign_association",
        "displayName": "Derived Relationship between driver and ride_assign",
        "associationType": "common:has",
        "fromType": "ugottaride:driver",
        "toType": "ugottaride:ride_assign",        
        "scopeFilter": "true",
        "mappings": {
            "attributes": {
                "driverid": "this.attributes.'driverid'.value"                
            }
        }
    },
    {
        "namespace": {
            "name": "ugottaride",
            "version": 1
        },
        "kind": "associationDerivation",
        "name": "ugottaride_ride_assign_to_driver_association",
        "displayName": "Derived Relationship between ride_assign and driver",
        "associationType": "common:has",
        "fromType": "ugottaride:ride_assign",
        "toType": "ugottaride:driver",        
        "scopeFilter": "true",
        "mappings": {
            "attributes": {
                "driverid": "this.attributes.'driverid'.value"                
            }
        }
    }
]


/fsoc_projects/my_tenant/ugottaride/objects/model/association-derivations/ride_assign_vehicle-associationDerivations.json

[
    {
        "namespace": {
            "name": "ugottaride",
            "version": 1
        },
        "kind": "associationDerivation",
        "name": "ugottaride_vehicle_to_ride_assign_to_association",
        "displayName": "Derived Relationship between vehicle and ride_assign",
        "associationType": "common:has",
        "fromType": "ugottaride:vehicle",
        "toType": "ugottaride:ride_assign",        
        "scopeFilter": "true",
        "mappings": {
            "attributes": {
                "vin": "this.attributes.'vin'.value"                
            }
        }
    },
    {
        "namespace": {
            "name": "ugottaride",
            "version": 1
        },
        "kind": "associationDerivation",
        "name": "ugottaride_ride_assign_to_vehicle_association",
        "displayName": "Derived Relationship between ride_assign and vehicle",
        "associationType": "common:has",
        "fromType": "ugottaride:ride_assign",
        "toType": "ugottaride:vehicle",        
        "scopeFilter": "true",
        "mappings": {
            "attributes": {
                "vin": "this.attributes.'vin'.value"                
            }
        }
    }
]


Update the manifest!

We must manually update our manifest.json file since we manually created the association derivations. Otherwise the platform won’t know about our association derivations.


/fsoc_projects/my_tenant/ugottaride/manifest.json

        {
            "type": "fmm:associationDerivation",
            "objectsDir": "objects/model/association-derivations"
        }


Next Steps  

We’ll manually create the entity priorities.

Click here to continue