Defining Types
The first step is to create the types we need to model departments and roles. We will define one object type called
department
from which we can later create instances of department
objects.
We will also define three relations on the department
object type—owner
, member
, and viewer
—one for each of
the three roles that users can have.
Object Type
We use the setObjectType
mutation to create a new
object type called "department".
mutation CreateDepartmentObjectType {
setObjectType(type: {
name: "department"
displayName: "Department"
isSubject: false
ordinal: 0
status: []
}) {
objectType {
id
name
displayName
isSubject
ordinal
status
}
}
}
Results
{
"data": {
"setObjectType": {
"objectType": {
"id": 1,
"name": "department",
"displayName": "Department",
"isSubject": false,
"ordinal": 0,
"status": []
}
}
}
}
The value of the name
field is used to identify the object type and must be unique among all object types in the directory.
The input fields are described in more detail here.
Querying Object Types
To see that the department object types was indeed created, we can enumerate object types using the objectTypes query.
The following query retrieves the id
, name
, and displayName
fields of the first 10 object types that are not subject
and have an no modifier flags in their status
field:
query ListObjectTypes {
objectTypes(first: 10, where: {isSubject: false, status: {equals: []}}) {
nodes {
id
name
displayName
}
}
}
Results
{
"data": {
"objectTypes": {
"nodes": [
{
"id": 1,
"name": "department",
"displayName": "Department"
},
{
"id": 10004,
"name": "application",
"displayName": "Application"
},
{
"id": 10005,
"name": "resource",
"displayName": "Resource"
}
]
}
}
}
Relation Types
Now that we have created an object type, we can define relations that it can have with other objects.
We define three relations, viewer
, member
, and owner
, to represent the three roles that users can have in a
department.
Viewer
We'll start witht the viewer
relation.
mutation CreateDepartmentViewerRelationType {
setRelationType(type: {
objectType: {name: "department"}
name: "viewer",
displayName: "department::viewer"
ordinal: 1,
status: []
unions: []
}) {
relationType {
id
displayName
}
}
}
Results
{
"data": {
"setRelationType": {
"relationType": {
"id": 2,
"displayName": "department::viewer"
}
}
}
}
We specify the object type on which the relation can occur using the objectType
field. Here we referred to the
object type by name, but could also refer to it by ID, in which case we would use {id: 1}
(the ID of our newly
created department object type is 1
).
The name
field of relation types needs to be unique among all relation types defined on the same object type.
By convention, the displayName
of relation types is set to <object type name>::<relation type name>
.
The input fields are described in more detail here.
Member and Owner
A single GraphQL request can include multiple queries and mutations. We'll create the member
and owner
relation
types in a single request:
mutation CreateDepartmentMemberAndOwnerRelationTypes {
member: setRelationType(type: {
name: "member",
displayName: "department::member"
objectType: {name: "department"}
ordinal: 1,
status: []
unions: []
}) {
relationType {
id
}
}
owner: setRelationType(type: {
name: "owner",
displayName: "department::owner"
objectType: {name: "department"}
ordinal: 1,
status: []
unions: []
}) {
relationType {
id
}
}
}
Results
{
"data": {
"member": {
"relationType": {
"id": 3,
"displayName": "department::member"
}
},
"owner": {
"relationType": {
"id": 4,
"displayName": "department::owner"
}
}
}
}
When sending multiple instances of the same query or mutation in a single request, we need to provide them with
aliases to distinguish their respective results in the response's data
object.
Querying Relation Types
Let's run a query to see that all three relation types were created as intended.
query RelationTypes {
relationTypes(first: 3) {
nodes {
id
name
displayName
objectType {
name
}
ordinal
}
}
}
Results
{
"data": {
"relationTypes": {
"nodes": [
{
"id": 2,
"name": "viewer",
"displayName": "department::viewer",
"objectType": {
"name": "department"
},
"ordinal": 1,
},
{
"id": 3,
"name": "member",
"displayName": "department::member",
"objectType": {
"name": "department"
},
"ordinal": 1,
},
{
"id": 4,
"name": "owner",
"displayName": "department::owner",
"objectType": {
"name": "department"
},
"ordinal": 1,
}
]
}
}
}
The three relation types we created appear first because we gave them all a low ordinal
value (i.e. 1
).
Types with lower ordinal values are retruned first. When several types have the same ordinal value, as in our case,
they are sorted by ID.