Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with interface SelectFields and inline fragments #605

Closed
illambo opened this issue Mar 15, 2020 · 1 comment · Fixed by #607
Closed

Problem with interface SelectFields and inline fragments #605

illambo opened this issue Mar 15, 2020 · 1 comment · Fixed by #607

Comments

@illambo
Copy link
Contributor

illambo commented Mar 15, 2020

Versions:

  • graphql-laravel Version: 5.0.0-rc2
  • Laravel Version: 6.18.1
  • PHP Version: 7.2.22

Description:

I'm having problems with interface SelectFields and inline fragments.
The query seems does not extract the requested data from interface (see below query with inline fragments), maybe is related to SelectFields.

Steps To Reproduce:

  • Setup example
// migrations

Schema::create('humans', function (Blueprint $table) {
      $table->bigIncrements('id');
      $table->string('skin');
      $table->timestamps();
});

Schema::create('droids', function (Blueprint $table) {
      $table->bigIncrements('id');
      $table->string('metal');
      $table->timestamps();
});

// interface

class CharacterInterfaceType extends InterfaceType
{
    protected $attributes = [
        'name' => 'CharacterInterface',
        'description' => 'An example interface',
    ];

    public function fields(): array
    {
        return [
            'id' => [
                'type' => Type::id(),
            ],
        ];
    }

    /**
     * @param $root
     * @return Type
     */
    public function resolveType($root): ?Type
    {
        $type = null;

        if (! is_null($root)) {
            switch (get_class($root)) {
                case \App\Human::class: $type = GraphQL::type('Human'); break;
                case \App\Droid::class: $type = GraphQL::type('Droid'); break;
            }
        }

        return $type;
    }
}

// types

class DroidType extends GraphQLType
{
    protected $attributes = [
        'name' => 'Droid',
        'description' => 'A type',
        'model' => Droid::class,
    ];

    public function fields(): array
    {
        $characterInterface = GraphQL::type('CharacterInterface');
        return array_merge($characterInterface->getFields(), [
            'metal' => [
                'type'          => Type::string(),
                'description'   => 'The metal',
            ],

        ]);
    }

    public function interfaces(): array
    {
        return [
            GraphQL::type('CharacterInterface')
        ];
    }
}

class HumanType extends GraphQLType
{
    protected $attributes = [
        'name' => 'Human',
        'description' => 'A type',
        'model' => Human::class,
    ];

    public function fields(): array
    {
        $characterInterface = GraphQL::type('CharacterInterface');
        return array_merge($characterInterface->getFields(), [
            'skin' => [
                'type'          => Type::string(),
                'description'   => 'The skin',
            ],

        ]);
    }

    public function interfaces(): array
    {
        return [
            GraphQL::type('CharacterInterface')
        ];
    }
}

// query

class CharactersQuery extends Query
{
    protected $attributes = [
        'name' => 'characters',
        'description' => 'A query'
    ];

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

    public function args(): array
    {
        return [];
    }

    public function resolve($root, $args, $context, ResolveInfo $resolveInfo, Closure $getSelectFields)
    {
        /** @var SelectFields $fields */
        $fields = $getSelectFields();
        $select = $fields->getSelect();
        $relations = $fields->getRelations();

        // this example force to human extractions
        return \App\Human::select($select)->with($relations)->get(); // this  not work ... 
        //return \App\Human::with($relations)->get(); // this  not work ...
        //return \App\Human::get(); // !! this work ...
    }
}
  • Seed some human ..
  • Run query
query Characters {
  characters {
    __typename
    id
    ...on Droid {
      id
      metal
    }
    ...on Human {
      id
      skin
    }
  }
}
  • Check extracted data, human skin is null
@illambo
Copy link
Contributor Author

illambo commented Mar 20, 2020

Please @mfn can check pull request #607 , maybe can fix the problem.
Thanks

@mfn mfn closed this as completed in #607 Mar 23, 2020
mfn pushed a commit that referenced this issue Mar 23, 2020
* Fix interface fields selection, resolve issue #605

* Interface tests adaptation

* Add interface test targeted inline fragments and alias

* Update phpstan-baseline.neon

* Edit CHANGELOG.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants