首页 > 解决方案 > 如何在 graphql-laravel 中使用 UnionType?

问题描述

我的问题是 select *for table,这会禁用 with 或 select 函数,并n+1导致查询决定我是否与另一个表有关系的问题。它还禁用了减少查询的 GraphQL 属性

class ProductsQuery extends Query
{
    protected $attributes = [
        'name' => 'products',
    ];

    public function type(): Type
    {
        // return Type::nonNull(GraphQL::paginate('Product'));
        return Type::nonNull(GraphQL::type('ProductPaginateOrList'));
    }

    public function args(): array
    {
        return [
            // start paginate
            'paginate' => [
                'name' => 'paginate',
                'type' => Type::boolean(),
                'rules' => ['boolean'],
                'defaultValue' => true,
            ],
            'paginateLimit' => [
                'name' => 'paginateLimit',
                'type' => Type::int(),
                'rules' => ['required_if:paginate,true'],
                'defaultValue' => 15,
            ],
            'page' => [
                'name' => 'page',
                'type' => Type::int(),
                'rules' => ['required_if:paginate,true'],
            ],
            // end paginate
        ];
    }

    public function resolve($root, array $args, $context, ResolveInfo $info, SelectFields $fields)
    {
        $select = $fields->getSelect();
        $with = $fields->getRelations();

        return Product::query()
            ->select($select)
            ->with($with)
            ->when($args['paginate'], function ($q) use ($args) {
                return $q->paginate($args['paginateLimit'], ['*'], 'page', $args['page']);
            }, function ($q) {
                return $q->get();
            });
    }
}

class ProductPaginateOrList extends UnionType
{
    protected $attributes = [
        'name' => 'ProductPaginateOrList',
        'description' => 'Products with paginator or collection of products',
    ];

    public function types(): array
    {
        return [
            GraphQL::paginate('Product'),
            GraphQL::wrapType(
                'Product',
                'ProductData',
                DataType::class
            )
        ];
    }

    public function resolveType($root): Type
    {
        if ($root instanceof LengthAwarePaginator) {
            return GraphQL::paginate('Product');
        } elseif ($root instanceof Collection) {
            return GraphQL::wrapType(
                'Product',
                'ProductData',
                DataType::class
            );
        }
        return null;
    }
}
class DataType extends ObjectType
{
    public function __construct(string $typeName, string $customName = null)
    {
        $name = $customName ?: $typeName . 'Data';

        $config = [
            'name' => $name,
            'fields' => $this->getDataFields($typeName),
        ];

        $underlyingType = GraphQL::type($typeName);

        if (isset($underlyingType->config['model'])) {
            $config['model'] = $underlyingType->config['model'];
        }

        parent::__construct($config);
    }

    protected function getDataFields(string $typeName): array
    {
        return [
            'data' => [
                'type' => GraphQLType::listOf(GraphQL::type($typeName)),
                'description' => 'List of items',
                'resolve' => function ($data) {
                    return $data;
                },
                'selectable' => true,
            ],
        ];
    }
}

版本:

graphql-laravel 版本:7.2

Laravel 版本:8.61

PHP版本:8

问题详细!

标签: phplaravelgraphql

解决方案


推荐阅读