Hierarchy
Infrahub supports organizing nodes of similar types into a tree structure. Hierarchy mode enables ancestor and descendant queries, and allows filtering related data across multiple levels of the tree without direct relationships between every node.
Enabling hierarchy​
A hierarchy must be defined around a specific Generic to ensure that all nodes that are part of a given hierarchy share some attributes.
In the schema the attribute hierarchical: true on a Generic activates the hierarchical mode.
All nodes inheriting from this main
Genericwill automatically have the hierarchical mode enabled as well. Each node can only inherit from oneGenericwith hierarchical mode at the same time.
- Groups can be organized in a hierarchy by default which makes it possible to query the members of all sub-groups at once.
- Assuming we have defined a
Personobject connected to aCityobject, which itself is part of a hierarchy ofLocation(Region>Country>City), it will be possible to query allPersonperCountryor perRegionnatively without having a direct relationship betweenPersonandCountry.
All nodes with hierarchical support will automatically have 2 new relationships:
parentof cardinality onechildrenof cardinality many
Specify the structure of the hierarchy​
By default, any node inheriting from the main Generic can be a parent or a children, which might not be always desirable. It's possible to limit which type of models are valid parent or children in the schema with the attributes parent & children at the node level.
In the example below, we are defining a hierarchy of Location with Region, Country and City.
Only Country can be defined as children of a Region and only City can be defined as children of a Country
version: '1.0'
generics:
- name: Generic
namespace: Location
hierarchical: true
attributes:
- name: name
kind: Text
nodes:
- name: Region
namespace: Location
inherit_from: ["LocationGeneric"]
parent: ""
children: "LocationCountry"
- name: Country
namespace: Location
inherit_from: ["LocationGeneric"]
parent: "LocationRegion"
children: "LocationCity"
- name: City
namespace: Location
inherit_from: ["LocationGeneric"]
parent: "LocationCountry"
children: ""
Query data around a hierarchy in GraphQL​
In GraphQL queries, all nodes with hierarchical support will have 2 additional fields:
ancestorsto access all ancestors of a given nodes (parent of parents)descendantsto access all descendants of a given nodes (children of children)
ancestors and descendants are separated from parent and children to clearly indicate that we need to query the hierarchy and not the directly connected nodes.
For all relationships of cardinality many, it's possible to query all the objects associated with descendants nodes as well by providing the include_descendants flag.
As an example, the GraphQL query below will query the members of all groups that are defined as children of Group1.
Assuming that Group1 has 2 sub-groups defined Group A and Group B (AKA children), the query will return the members of Group1, Group A and Group B together.
query {
CoreStandardGroup(name__value: "Group1") {
edges {
node {
id
display_label
members(include_descendants: true) {
count
edges {
node {
id
display_label
}
}
}
}
}
}
}
Related concepts​
- Generics & inheritance — How generics and
inherit_fromwork - Groups — Groups use hierarchy to enable nested member queries