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
relationship
for a relationship object. returnByDefault
(booleantrue, false
)-
Specifies whether the relationship should be returned as part of the response. The
returnByDefault
property 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
manager
property has areversePropertyName
ofreports
. resourceCollection
(JSON object)-
The collection of resources (objects) on which this relationship is based (for example,
managed/user
objects).
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
_ref
property is a derived path that is a combination of_refResourceCollection
and 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 asbjensen
andpsmith
. _refProperties
(JSON object)-
Any required properties from the relationship that should be included in the managed object. The
_refProperties
field includes a unique ID (_id
) and the revision (_rev
) of the object._refProperties
can also contain arbitrary fields to support metadata within the relationship.