Configuring relationships
Relationships are references between managed objects. They are defined in your managed object configuration file. You can interact with relationships over REST using the relationship’s endpoint, openidm/managed/user/userName/relationshipName?_queryFilter=true.
Learn more about relationships in:
Learn more about interacting with relationships over REST in:
When modeling relationships, be aware of bidirectional relationships and model them properly in your schema.
Roles and Organizations are implemented using relationships, but you can create relationships between any managed object type.
You can also:
-
Configure IDM to validate relationships when they’re created.
-
Create custom relationship properties.
-
Create custom relationships.
-
Update relationship-derived vritual properties by configuring relationship change notifications.
-
Require the system to validate relationships when they’re created.
IDM maintains referential integrity by deleting the relationship reference if the object referred to by that relationship is deleted.
Example relationship: manager
The default configuration includes a relationship named manager that lets you configure a relationship between two managed users. This relationship is a good example for understanding how relationships work.
The default manager relationship is configured as follows:
"manager" : {
"type" : "relationship",
"validate" : true,
"reverseRelationship" : true,
"reversePropertyName" : "reports",
"description" : "Manager",
"title" : "Manager",
"viewable" : true,
"searchable" : false,
"usageDescription" : "",
"isPersonal" : false,
"properties" : {
"_ref" : {
"description" : "References a relationship from a managed object",
"type" : "string"
},
"_refProperties" : {
"description" : "Supports metadata within the relationship",
"type" : "object",
"title" : "Manager _refProperties",
"properties" : {
"_id" : {
"description" : "_refProperties object ID",
"type" : "string"
}
}
}
},
"resourceCollection" : [
{
"path" : "managed/user",
"label" : "User",
"query" : {
"queryFilter" : "true",
"fields" : [
"userName",
"givenName",
"sn"
]
}
}
],
"userEditable" : false
},
Retrieve relationship data
There are two ways to retrieve data about a relationship over REST, querying the relationship endpoint or reading relationship fields.
Querying the relationship endpoint supports filtering and paginating the results. It’s the safest and most efficient way of retrieving data.
Reading relationship fields does not support filtering or paginating results. To prevent problems that could result from requesting a large amount of data, use this method only in situations where you are certain there are few results.
Query a relationship endpoint
You can retrieve a managed object’s relationship data by querying the relationship endpoint. The endpoint’s name is the name of the relationship field.
A relationship endpoint query can use the _queryFilter and _pageSize parameters to filter and paginate large numbers of results. To avoid the risk of a large query overwhelming your system, use this method whenever possible.
The _queryFilter parameter can filter by any fields which are indexed attributes of the related object.
The following example demonstrates querying managed user bjensen for all reports:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/managed/user/bjensen/reports?_queryFilter=true"
{
"result": [
{
"_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4311",
"_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4312",
"_ref": "managed/user/psmith",
"_refResourceCollection": "managed/user",
"_refResourceId": "psmith",
"_refProperties": {
"_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4311",
"_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4312"
}
},
{
"_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4934",
"_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4935",
"_ref": "managed/user/scarter",
"_refResourceCollection": "managed/user",
"_refResourceId": "scarter",
"_refProperties": {
"_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4934",
"_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4935"
}
}
],
"resultCount": 2,
"pagedResultsCookie": null,
"totalPagedResultsPolicy": "NONE",
"totalPagedResults": -1,
"remainingPagedResults": -1
}
The following example demonstrates querying managed user bjensen for all reports where the sn is Smith:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/managed/user/bjensen/reports?_queryFilter=sn+eq+'Smith'&_pageSize=1"
{
"result": [
{
"_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4311",
"_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4312",
"_ref": "managed/user/psmith",
"_refResourceCollection": "managed/user",
"_refResourceId": "psmith",
"_refProperties": {
"_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4311",
"_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4312"
}
}
],
"resultCount": 1,
"pagedResultsCookie": null,
"totalPagedResultsPolicy": "NONE",
"totalPagedResults": -1,
"remainingPagedResults": -1
}
You can also pass the _fields query parameter to include them in the response, demonstrated here with userName and phoneNumber:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \ \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/managed/user/bjensen/reports?_queryFilter=sn+eq+'Smith'&_fields=userName,phoneNumber&_pageSize=1"
{
"result" : [ {
"_id" : "78483e83-9577-40cd-a1d4-6ea0a896e916-45700",
"_rev" : "78483e83-9577-40cd-a1d4-6ea0a896e916-45701",
"_ref" : "managed/user/psmith",
"_refResourceCollection" : "managed/user",
"_refResourceId" : "psmith",
"_refResourceRev" : "d776f795-512f-4c09-a673-1f081a8ef3ef-4955",
"_refProperties" : {
"_id" : "78483e83-9577-40cd-a1d4-6ea0a896e916-45700",
"_rev" : "78483e83-9577-40cd-a1d4-6ea0a896e916-45701"
},
"userName" : "psmith",
"phoneNumber" : "0831245986"
} ],
"resultCount" : 1,
"pagedResultsCookie" : null,
"totalPagedResultsPolicy" : "NONE",
"totalPagedResults" : -1,
"remainingPagedResults" : -1
}
When you query an endpoint which is a collection, you must use the _queryFilter parameter, or you’ll receive an error with an HTTP 400 error code. If you don’t want to filter the results, pass _queryFilter=true.
Learn more about _queryFilter in Query and Constructing queries.
Read relationship fields
To read relationship fields, query a managed object and pass the _fields parameter to request associated data fields.
Do not use _fields to request a field that is a relationship with more than a few members, as this data cannot be filtered or paginated.
|
The following example reads a singleton relationship (manager) associated with a managed user (psmith):
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/managed/user/psmith?_fields=manager"
{
"_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-17222",
"_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-17223",
"_ref": "managed/user/bjensen",
"_refResourceCollection": "managed/user",
"_refResourceId": "bjensen",
"_refProperties": {
"_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-17222",
"_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-17223"
}
}
When you’re reading relationship fields, you can use the managed object endpoint directly using the following syntax:
-
relatedObject/property(for a simple string value) -
relatedObject/*/property(for an array of values)
This example demonstrates retrieving the mail and phoneNumber properties from psmith’s manager using this method:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/managed/user/psmith?_fields=manager/mail,manager/phoneNumber" { "_id": "psmith", "_rev": "0000000014c0b68d", "manager": { "_rev": "000000005bac8c10", "_id": "bjensen", "phoneNumber": "12345678", "mail": "bjensen@example.com", "_ref": "managed/user/bjensen", "_refResourceCollection": "managed/user", "_refResourceId": "bjensen", "_refProperties": { "_id": "42418f09-ad6c-4b77-bf80-2a12d0c44678", "_rev": "00000000288b921e" } } }
Create a relationship
To create a relationship between two managed objects, send a POST request to the relationship’s endpoint with a _ref parameter containing the path to the other side of the relationship.
For example, suppose the user psmith has the user bjensen as a manager. The following call creates the manager relationship between them:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--header "Content-Type: application/json" \
--request POST \
--data '{
"_ref" : "managed/user/bjensen"
}' \
"http://localhost:8080/openidm/managed/user/psmith/manager"
{
"_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82148",
"_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82149",
"_ref": "managed/user/bjensen",
"_refResourceCollection": "managed/user",
"_refResourceId": "bjensen",
"_refProperties": {
"_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82148",
"_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82149"
}
}
To learn more about the _ref parameter or the relationship reference properties in general, refer to Relationship properties.
Creating a relationship as part of a created object
In addition to creating a relationship between two existing managed objects, you can create a relationship at the same time as you create a managed object. For example, imagine that you are creating a new user, psmith, and that psmith’s manager will be bjensen. You would create psmith’s user entry, and reference bjensen’s entry with the _ref property, as follows:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--header "If-None-Match: *" \
--header "Content-Type: application/json" \
--request PUT \
"http://localhost:8080/openidm/managed/user/psmith" \
--data '{
"_id": "psmith",
"_rev": "00000000ec41097c",
"sn": "Smith",
"userName": "psmith",
"givenName": "Patricia",
"displayName": "Patti Smith",
"description": "psmith - new user",
"mail": "psmith@example.com",
"phoneNumber": "0831245986",
"manager": {
"_ref": "managed/user/bjensen"
}
}'
| Relationship information is not returned by default. To show the relationship in psmith’s entry, you must explicitly request her manager entry, as follows: |
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/managed/user/psmith?_fields=manager"
{
"_id": "psmith",
"_rev": "00000000ec41097c",
"manager": {
"_ref": "managed/user/bjensen",
"_refResourceCollection": "managed/user",
"_refResourceId": "bjensen",
"_refProperties": {
"_id": "ffc6f0f3-93db-4939-b9eb-1f8389a59a52",
"_rev": "0000000081aa991a"
}
}
}
To learn more about the _ref parameter or the relationship reference properties in general, refer to Relationship properties.
Update a relationship
You can update a managed object’s relationship data by making a PUT request to its endpoint. The endpoint’s name is the name of the relationship field.
When you update a relationship, the related objects automatically update to reflect the new state. In the following example, scarter’s reports entry is automatically updated when the change to psmith’s manager entry is updated.
The following example updates psmith’s manager to scarter:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \ \
--header "Accept-API-Version: resource=1.0" \
--header "If-Match: *" \
--header "Content-Type: application/json" \
--request PUT \
--data '{
"_ref":"managed/user/scarter"
}' \
"http://localhost:8080/openidm/managed/user/psmith/manager"
{
"_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82148",
"_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-108753",
"_ref": "managed/user/scarter",
"_refResourceCollection": "managed/user",
"_refResourceId": "scarter",
"_refProperties": {
"_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82148",
"_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-108753"
}
}
Delete a relationship
You can delete a relationship by sending a DELETE request to its endpoint.
The following example deletes psmith’s manager:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \\
--header "Accept-API-Version: resource=1.0" \
--request DELETE \
"http://localhost:8080/openidm/managed/user/psmith/manager"
Relationship properties
Relationships have the following specific configurable properties:
| Most of these properties apply to any managed object type. |
type(string)-
The object type. Must be
relationshipfor a relationship object. returnByDefault(booleantrue, false)-
Specifies whether the relationship should be returned as part of the response. The
returnByDefaultproperty is not specific to relationships. This flag applies to all managed object types. However, relationship properties are not returned by default, unless explicitly requested. reverseRelationship(booleantrue, false)-
Specifies whether this is a bidirectional relationship.
reversePropertyName(string)-
The corresponding property name, in the case of a bidirectional relationship. For example, the
managerproperty has areversePropertyNameofreports. resourceCollection(JSON object)-
The collection of resources (objects) on which this relationship is based (for example,
managed/userobjects).
Relationship reference properties
When you have defined a relationship, you can use the relationship properties to reference one managed user from another. These properties make up a relationship reference:
_ref(JSON object)-
Specifies how the relationship between two managed objects is referenced.
The value of the
_refproperty is a derived path that is a combination of_refResourceCollectionand a URL-encoded_refResourceId. _refResourceCollection-
Specifies the container of the referenced object (for example,
managed/user). _refResourceId-
Specifies the ID of the referenced object. This is generally a system-generated UUID, such as
9dce06d4-2fc1-4830-a92b-bd35c2f6bcbb. For clarity, this documentation uses client-assigned IDs such asbjensenandpsmith. _refProperties(JSON object)-
Any required properties from the relationship that should be included in the managed object. The
_refPropertiesfield includes a unique ID (_id) and the revision (_rev) of the object._refPropertiescan also contain arbitrary fields to support metadata within the relationship.