Lets say I got a user Type
class UserType(DjangoObjectType):
class Meta:
model = User
fields = [
"fieldA",
"fieldB",
"relationshipA",
"relationshipB"
]
And I want fieldB
and relationshipB
to be visible only to the owner (user).
What is the best strategy to do this?
Initially Ive created a PublicUserType
excluding private fields, but quickly I realized that it might not be scalable because not only I'll have to create private representation for UserType
I'll might also create private representation for any relationship (relationshipA
etc), and proper resolvers, and duplicate fragments etc.
Is there a best practice here?
My solution is:
Create decorators.py
file
from functools import wraps
from graphql import GraphQLError
from api.utils import snake_to_camel_case
def private_field(func):
@wraps(func)
def wrapper(self, info):
user = info.context.user
if user.id != self.id:
field_name = func.__name__.replace('resolve_', '')
field_name_camel_cased = snake_to_camel_case(field_name)
raise GraphQLError(f'You do not have permissions to access {field_name}')
return func(self, info)
return wrapper
snake_to_camel_case func:
def snake_to_camel_case(string):
components = string.split('_')
return components[0] + ''.join(x.title() for x in components[1:])
and finally on my schema file resolver:
@private_field
def resolve_private_field(self, info):
return self.private_field
Response should look something like that:
{
"errors": [
{
"message": "You do not have permissions to access privateField",
...
Now obviously this solution is super specific for my needs atm but it should be easy enough to make it more generic and scalable for any scenario.