Как получить JSON с GraphQL в Laravel? Я пытался использовать смешанный скалярный тип в аргументах, но получил ошибку - PullRequest
0 голосов
/ 16 января 2020

У меня есть следующий код для компонента Vue. js, который использует Apollo для вызова приложения Laravel с установленным GraphQL (используя пакет: https://github.com/rebing/graphql-laravel):

const INVITES_QUERY = gql`
  query INVITES_QUERY {
    invites(limit: 75, page: 1, orderBy: { field: ID, direction: DESC }) {
      id
      email
      status
    }
  }
`;

 export default {
   name: 'MyInvites',
   components: { InviteTable },
   apollo: {
      invites: INVITES_QUERY
   },
... Continue

Чтобы иметь возможность получить аргумент orderBy (который является JSON объектом) из этого запроса GraphQL, в моем InvitesQuery.php я использовал new Mixed() (из пакета https://github.com/mll-lab/graphql-php-scalars) в качестве типа аргумента:

<?php

namespace App\GraphQL\Queries;

use App\Invite;
use GraphQL\Type\Definition\Type;
use Illuminate\Support\Facades\Auth;
use MLL\GraphQLScalars\Mixed;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Query;

class InvitesQuery extends Query
{
    protected $attributes = [
        'name' => 'invites',
    ];

    public function type(): Type {
        return Type::listOf(GraphQL::type('Invite'));
    }

    public function args(): array
    {
        return [
            'limit' => ['name' => 'limit', 'type' => Type::int()],
            'orderBy' => ['name' => 'orderBy', 'type' => new Mixed()],
            'page' => ['name' => 'page', 'type' => Type::int()]
        ];
    }

    public function resolve($root, $args) {
        if (!Auth::user()) {
            throw new \Error('User not authenticated', 403);
        }

        return Invite::where('friend_id', Auth::user()->id)
            ->orderBy($args['orderBy']['field'], $args['orderBy']['direction'])
            ->paginate($args['limit'], ['*'], 'page', $args['page']);
    }
}

Дело в том, что 'orderBy' => ['name' => 'orderBy', 'type' => new Mixed()], работал хорошо, если у меня только один запрос с использованием этого типа аргумента. Конечно, у меня нет только одного запроса, который требует разбивки на страницы, поэтому у меня есть еще один с точно таким же методом args, и это выдает мне следующую ошибку каждый раз, когда я запускаю любой запрос GraphQL:

GraphQL\Error\InvariantViolation: Schema must contain unique named types but contains multiple types named "Mixed"

Если я удаляю второй Запрос, который использует этот 'orderBy' => ['name' => 'orderBy', 'type' => new Mixed()],, первый работает нормально. Если я включу второй снова, все они перестанут работать с этой ошибкой. Я понял, что эта ошибка описывает, что есть две вещи, использующие один и тот же тип Смешанный , но я не знаю, почему это неправильно и как это исправить, так как в обоих запросах мне нужно получить это JSON из внешнего интерфейса, который будет использоваться в моей нумерации страниц. Я попытался использовать Mixed::class вместо new Mixed(), но он никогда не работает, в то время как new Mixed() работает для одного.

Я ценю любую помощь в этом вопросе. Спасибо!

--- ОБНОВЛЕНИЕ:

Я смог использовать Смешанный тип в более чем одном месте с помощью синглтона, подобного этому :

<?php

namespace App\GraphQL\Types;

use MLL\GraphQLScalars\Mixed;

abstract class MixedType
{
    private static $mixedType;

    static function get() {
        if (!self::$mixedType) {
            self::$mixedType = new Mixed();
        }

        return self::$mixedType;
    }
}

И изменив запрос, чтобы использовать его следующим образом:

'orderBy' => ['name' => 'orderBy', 'type' => MixedType::get()],

Что вы думаете об этом решении?

...