Reputation: 1687
I'm working with a very large normalized and recursive object. I want to get the list of all recursive items. Should I use an argument or a custom resolver?
My object looks like:
{
products: [{
product_id: "car",
bundle_id: 5
},{
product_id: "door"
bundle_id: 6
},
{ product_id: "wheel" },
{ product_id: "metal" },
{ product_id: "glass" }],
bundles: [{
bundle_id: 5,
options: [{product_id: "door"},{product_id: "wheel"}]
},
{
bundle_id: 6,
options: [{product_id: "metal"},{product_id: "glass"}]
}]
}
You might notice that "car" is a bundle
that has a door
and a wheel
. "door" is also a bundle
that has metal
and glass
. This structure could recurse indefinitely. That is, a bundle could have infinitely more bundle products underneath it.
I want to get a list of all products for a bundle (example: "car"). What is the best approach?
I see two options.
First Option - use a custom resolver, for example child_products
that would recurse and resolve to a flat array of all children:
products(product_id: "car") {
product_id
bundle {
options {
product_id
}
}
child_products {
product_id
bundle {
options {
product_id
}
}
}
}
Second Option - use an argument that specifies including all children:
products(product_id: "car", include_children: true) {
product_id
bundle {
options {
product_id
}
}
}
I'm going to build a JS library that can take the array of products and options and build the nested structure. Please let me know what you think is the right way. Thanks!
Upvotes: 0
Views: 140
Reputation: 84697
You should not need an argument like include_children
because a client's query will be sufficient to determine whether to include the nodes or not -- if a client doesn't need the nodes, it can simply omit the appropriate field.
Based on the provided JSON object, I would expect a schema that looks something like this:
type Query {
product(id: ID!): Product
}
type Product {
id: ID!
bundle: Bundle
}
type Bundle {
id: ID!
options: [Product!]!
}
which would let you make a query like:
query {
product(id: "car") {
id
bundle {
options {
id
bundle {
id
# and so on...
}
}
}
}
}
The actual depth of this query would be left up to the client's needs. Recursive type definitions like this do present a possible attack vector and so you should also look into using a library like graphql-depth-limit or graphql-query-complexity.
Upvotes: 1