Some time ago I came up with another solution, which is the same approach like @WuDo suggested.
The idea is to flatten the tree on data level using IDs to reference them (each child with it’s parent) and marking the roots of the tree, then on client side build up the tree again recursively.
This way you should not worry about limiting the depth of your query like in @samcorcos’s answer.
schema:
type Query {
tags: [Tag]
}
type Tag {
id: ID!
children: [ID]
root: Boolean
}
response:
{
"tags": [
{"id": "1", "children": ["2"], "root": true},
{"id": "2", "children": [], "root": false}
]
}
client tree buildup:
import find from 'lodash/find';
import isArray from 'lodash/isArray';
const rootTags = [...tags.map(obj => ({...obj})).filter(tag => tag.root === true)];
const mapChildren = childId => {
const tag = find(tags, tag => tag.id === childId) || null;
if (isArray(tag.children) && tag.children.length > 0) {
tag.children = tag.children.map(mapChildren).filter(tag => tag !== null);
}
}
const tagTree = rootTags.map(tag => {
tag.children = tag.children.map(mapChildren).filter(tag => tag !== null);
return tag;
});
// Update 2022-08-16 Fixed typo