You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have models where I want to restrict the content of some fields based on the relationship between the user and the current instance of that model.
The challenge is that if I write custom field resolvers for each field that I want to alter, I end up doing a db query for each such field, which ends up becoming really slow if I get a whole QuerySet of the node type.
How can I prevent doing a query for each and every field resolution?
Example
If I have a model Book and each book has an author field which is a FK to the user model.
Then on the BookNode I have the field-level checks:
defresolve_authors_only_field1(self, info):
user=info.context.userifuserinself.author_set.all():
returnself.authors_only_field1return"some default"# In case of a required field typedefresolve_authors_only_field2(self, info):
user=info.context.userifuserinself.author_set.all():
returnself.authors_only_field2returnNone# In case of an optional field type
Performance Bottleneck
This does work, but as far as I understand it will do a db query for executing every field resolver!
Meaning: If I get 20 books and I have 20 restricted/conditional fields, I end up doing 400 db queries. 😐
Solution Ideas
Mental Inspiration
FYI: As an inspiration I was also looking at similar multi-/cross-field challenges.
I also looked at how Django Form validation tries to allow something similar.
Single field validation:
defvalidate_myfield(self, value):
...
Cross-field validation:
defvalidate(self, data):
...
Solution idea 1: Cross-field resolver hook
Being able to change the fields based on a hook after individual fields have been resolved:
Single field resolver hook:
defresolve_myfield(self, info):
...
Cross-field resolver hook:
defresolve_fields(self, info, data):
...
Solution idea 2: Dynamic fields/only-fields/exclude-fields
Make it possible to change the fields/only-fields/exclude-fields attributes at runtime. (e.g. when starting to resolve the node?)
Or allow fields/only-fields/exclude-fields to accept a function that will be called when resolving the node.
Update: @jkimbo pointed out that it’s not a good idea to change the types at runtime and that the schema should be static.
Alternative Ideas
Changing the type dynamically when resolving: #79 (comment)
(Nice idea, but might end up adding more complexity and types than necessary.)
The Challenge
I have models where I want to restrict the content of some fields based on the relationship between the user and the current instance of that model.
The challenge is that if I write custom field resolvers for each field that I want to alter, I end up doing a db query for each such field, which ends up becoming really slow if I get a whole QuerySet of the node type.
How can I prevent doing a query for each and every field resolution?
Example
If I have a model
Book
and each book has anauthor
field which is a FK to the user model.Then on the
BookNode
I have the field-level checks:Performance Bottleneck
This does work, but as far as I understand it will do a db query for executing every field resolver!
Meaning: If I get 20 books and I have 20 restricted/conditional fields, I end up doing 400 db queries. 😐
Solution Ideas
Mental Inspiration
FYI: As an inspiration I was also looking at similar multi-/cross-field challenges.
I also looked at how Django Form validation tries to allow something similar.
Single field validation:
Cross-field validation:
Solution idea 1: Cross-field resolver hook
Being able to change the fields based on a hook after individual fields have been resolved:
Single field resolver hook:
Cross-field resolver hook:
Solution idea 2: Dynamic fields/only-fields/exclude-fields
Make it possible to change the fields/only-fields/exclude-fields attributes at runtime. (e.g. when starting to resolve the node?)
Or allow fields/only-fields/exclude-fields to accept a function that will be called when resolving the node.
Update: @jkimbo pointed out that it’s not a good idea to change the types at runtime and that the schema should be static.
Alternative Ideas
Changing the type dynamically when resolving: #79 (comment)
(Nice idea, but might end up adding more complexity and types than necessary.)
Overwriting the resolver entirely: #79 (comment)
Additional context
If there are any questions to better explain my scenario/user-cases/etc.
Please feel free to ask and I will do my best to explain. :)
Comments
I really wonder if there is a smarter / more intuitive way of rewriting my code to not do a query per field. 🤔
The text was updated successfully, but these errors were encountered: