如何在 Laravel Rebing GraphQL 中使用“隐私”属性函数?

Posted

技术标签:

【中文标题】如何在 Laravel Rebing GraphQL 中使用“隐私”属性函数?【英文标题】:How to use the 'privacy' attribute function in Laravel Rebing GraphQL? 【发布时间】:2020-10-17 23:01:23 【问题描述】:

我正在使用 Laravel GraphQL 开发一个 graphql API。

如文档“隐私”部分所示,应该可以将回调函数添加到 GraphQLType 字段隐私属性。当回调返回 false 时,该字段应该返回 null。

类似于 laravel graphql Docs 中的示例,我添加了一个隐私回调,如下所示:

public function fields(): array 
    return [
        'email'               => [
            'type'        => Type::string(),
            'description' => 'The email of user',
            'privacy'     => function(User $user): bool 
                return $user->isMe();
            
        ],
    ];

在我看来,这个回调函数永远不会被调用。 我read something 提出了一个可能的要求,即我应该使用 $getSelectFields 函数来解决我的查询,以手动查询 $fields 和选定的列。但不幸的是 $select

 public function resolve($root, $args, $context, ResolveInfo $info, Closure $getSelectFields) 
    $fields = $getSelectFields();
    $with = $fields->getRelations(); // empty array
    $select = $fields->getSelect(); // empty array

    return User::select($select)->with($with)->get();

在我的情况下,这没有任何区别。

在我的查询解析器中,我执行以下操作:

public function resolve($root, $args, $context, ResolveInfo $info, Closure $getSelectFields) 

    /** @var SelectFields $fields */
    $fields = $getSelectFields();
    $select = $fields->getSelect();
    $with = $fields->getRelations();

    exit(var_dump($fields)); // #RESULT

我的结果如下所示:

object(Rebing\\GraphQL\\Support\\SelectFields)#4668 (2)  
    [\"select\":\"Rebing\\GraphQL\\Support\\SelectFields\":private]=>  array(0)   
    [\"relations\":\"Rebing\\GraphQL\\Support\\SelectFields\":private]=>  array(0)  

所以我的问题是:“我如何在 Laravel Rebing GraphQL 中使用隐私属性回调?”

我正在使用:

php 7.3 Laravel 7.17 Rebing Graphql Laravel 5.1

提前致谢,

问候朱尔斯

【问题讨论】:

有人可以帮我解决这个问题吗?解决此目的的任何类型的自定义解决方法都将非常耗时.. :/ 【参考方案1】:

关于我的用例的更多详细信息 EpUser.php

namespace App\GraphQL\Type;

use App\CommunityImage;
use App\User;
use Carbon\Carbon;
use GraphQL\Type\Definition\Type;
use Illuminate\Support\Facades\Auth;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Type as GraphQLType;

class EpUser extends GraphQLType 
    protected $attributes = [
        'name'        => 'EpUser',
        'description' => 'A type',
        'model'       => User::class,                                                 
    ];

    public function fields(): array 
        return [
            'id'                  => [
                'type'        => Type::nonNull(Type::int()),
                'description' => 'The id of the user',
                'privacy'     => function(User $user): bool 
                    return false;
                
            ],
            'email'               => [
                'type'        => Type::string(),
                'description' => 'The email of user',
                'privacy'     => function(User $user): bool 
                    return $user->isMe();                                                
                
            ],
            'firstName'           => [
                'type'        => Type::string(),
                'description' => 'The firstName of user'
            ],
            'lastName'            => [
                'type'        => Type::string(),
                'description' => 'The lastName of user'
            ],
            'fullName'            => [
                'type'        => Type::string(),
                'description' => 'The fullName of user',
                'selectable'  => false,
                'resolve'     => function(User $user) 
                    return $user->firstName . " " . $user->lastName;
                
            ],
            'gender'              => [
                'type'        => Type::string(),
                'description' => 'The gender of the user'
            ],
            'isOnline'            => [
                'type'        => Type::boolean(),
                'description' => '',
                'selectable'  => false,
                'resolve'     => function(User $user, $args) 
                    return $user->isOnline();
                
            ]
        ];
    

    [...]

这是应以用户分页对象响应的 UsersQuery,其中包含具有隐私属性的用户数组:

UsersQuery.php

namespace App\GraphQL\Query;

use App\Artist;
use App\FilePath;
use Closure;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Query;
use Illuminate\Support\Facades\Auth;
use GraphQL\Type\Definition\ResolveInfo;
use Rebing\GraphQL\Support\Facades\GraphQL;

use App\User;

class UsersQuery extends Query 
    protected $attributes = [
        'name'        => 'UsersQuery',
        'description' => 'A query',
        'model'       => User::class,
    ];

    public function type(): Type 
        return GraphQL::type('userPagination');
    

    public function authorize($root, array $args, $ctx, ResolveInfo $resolveInfo = NULL, $getSelectFields = NULL): bool 
        return Auth::check();
    

    public function args(): array 
        return [
            'id'         => [
                'type'        => Type::int(),
                'description' => 'The id of the user'
            ],
            'slug'       => [
                'type'        => Type::string(),
                'description' => 'The slug of the user'
            ],
            'pagination' => [
                'type'        => Type::nonNull(GraphQL::type('paginationInput')),
                'description' => 'The pagination of the users to query',
                'rules'       => 'required',
            ],
            'search'     => [
                'type'        => Type::string(),
                'description' => 'a string to search for users'
            ],
            'roles'      => [
                'type'        => Type::listOf(Type::string()),
                'description' => 'The roles of the user',
                'rules'       => 'sometimes|required|array|in:user,developer,administrator'
            ]
        ];
    

    public function resolve($root, $args, $context, ResolveInfo $info, Closure $getSelectFields) 
        if(isset($args['id']) || isset($args['slug'])) 
            if(isset($args['slug'])) 
                $user = User::where('slug', $args['slug'])->first();
             else 
                $user = User::find($args['id']);
            
            return [
                'items'     => $args['pagination']['limit'] > 0 && $user ? [$user] : NULL,
                'itemTotal' => $user ? 1 : 0
            ];
        

        $sortBy = $args['pagination']['sortBy'] ?? 'id';
        $sortByDesc = isset($args['pagination']['sortByDesc']) ? $args['pagination']['sortByDesc'] : true;
        $sortByType = $sortByDesc ? 'desc' : 'asc';

        $search = false;

        if(isset($args['search']) && $args['search']) 
            $search = true;
            $query = User::search($args['search']);
         else 
            $query = User::query();
        

        if(!empty($sortBy)) 
            $query->orderBy($sortBy, $sortByType);
        

        // Todo: eloquent search can't serach for whereHas
        if(isset($args['roles']) && !$search) 
            if(is_array($args['roles'])) 
                foreach($args['roles'] as &$role) 
                    $query->whereHas('roles',
                        function($q) use ($role) 
                            $q->where('name', $role);
                        );
                
             else 
                $query->whereHas('roles',
                    function($q) use ($args) 
                        $q->where('name', $args['roles']);
                    );
            
        

        if($search) 
            $userPaginationObject = [
                'itemTotal' => $query->count(),
                'items'     => $query->getWithLimitAndOffset($args['pagination']['limit'],
                    $args['pagination']['offset'])
            ];
         else 
            $userPaginationObject = [
                'itemTotal' => $query->count(),
                'items'     => $query->limit($args['pagination']['limit'])->offset($args['pagination']['offset'])->get()
            ];
        

        return $userPaginationObject;
    

【讨论】:

以上是关于如何在 Laravel Rebing GraphQL 中使用“隐私”属性函数?的主要内容,如果未能解决你的问题,请参考以下文章

我们如何从 GraphQL 的 RequestContextHolder 获取 GraphQL 的 HttpServletRequest(DefaultGlobalContext)(使用 graphq

AWS AppSync 与 Laravel 的正确集成?

无法使用 graphq-request 表示嵌套对象输入类型的数组

如何在 android 客户端中使用 graphql 订阅

如何对graphQL中的字段进行运行时数据操作?

在 GraphQL 对象查询中使用变量