1

I have a case where I need to hide field values on a Type based on another field but also show it in some cases based on the context.

So for example, I have a Type like such:

type Profile {
    id: ID! @cacheKey

    "Display name of the profile"
    display_name: String!

    "Handle / Slug of the profile"
    handle: Handle

    "If the profile is private"
    private: Boolean!

    "Connected socials this profile has added"
    socials: [ProfileSocial!]! @hasMany(relation: "publicSocials") @cache
}

Now I want to hide the socials field if private is true, however, I also want it to be visible if:

  1. You are the owner of this profile (user_id)
  2. You are an administrator
  3. You are friends with the user

I've looked into solving this by using Model Policies and scopes, but I haven't really found a good approach for this.

What I ended up doing was creating a FieldMiddleware which returns null based on few variables, for example:

    public function handleField(FieldValue $fieldValue, Closure $next)
    {
        $fieldValue = $next($fieldValue);
        $resolver = $fieldValue->getResolver();

        $fieldValue->setResolver(function ($root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) use ($resolver){
            if($root->private) {
                $authenticated = auth()->check();

                if($authenticated && auth()->id() !== $root->user_id || ! $authenticated) {
                    return null;
                }
            }

            return $resolver($root, $args, $context, $resolveInfo);
        });

        return $fieldValue;
    }

But I'm afraid this might be a bad approach, so what is the best way to solve this problem?

Tried using Model Policies but it affects hidden attributes which is not supported by Lighthouse. Tried using scopes but I can't get the models attributes before the builder so I can't conditionally hide fields. Tried using a field middleware but might be a bad approach.

Edwin Duoo
  • 11
  • 1

0 Answers0