laravel-graphql icon indicating copy to clipboard operation
laravel-graphql copied to clipboard

Support shorthand notation

Open KevinAsher opened this issue 7 years ago • 9 comments

Hi, just started using this lib. At the graphql-php docs here it says it supports a shorthand notation for defining fields for types. But when i try to use them, i get the following error:

Cannot use object of type GraphQL\\Type\\Definition\\NonNull as array

Here's the class type that uses the shorthand notation:

<?php

namespace App\GraphQL\Type;

use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Type as GraphQLType;

class UserType extends GraphQLType
{
    protected $attributes = [
        'name' => 'User',
        'description' => 'A user'
    ];

    /*
    * Uncomment following line to make the type input object.
    * http://graphql.org/learn/schema/#input-types
    */
    // protected $inputObject = true;

    public function fields()
    {
        return [
            'id' => Type::nonNull(Type::string()),  // <--- over here
            'email' => [
                'type' => Type::string(),
                'description' => 'The email of user'
            ],
            'name' => [
                'type' => Type::string(),
            ],
        ];
    }

    // If you want to resolve the field yourself, you can declare a method
    // with the following format resolve[FIELD_NAME]Field()
    protected function resolveEmailField($root, $args)
    {
        return strtolower($root->email);
    }

    protected function resolveNameField($root, $args)
    {
        return $root->name;
    }
}

KevinAsher avatar Feb 01 '18 00:02 KevinAsher

I'd check the resolve function in the query type. If you think the problem is the id in UserType, you can do:

'id' => [
            'type' => Type::nonNull(Type::string()),
            'resolve' => function ($root, $args) {
                    return 'foo';
            }
],

that will force the id field to return foo as string

faiverson avatar Feb 01 '18 02:02 faiverson

@faiverson, using 'id' => [ 'type' => Type::nonNull(Type::string())] solves the problem, but the main ideia here is the convenience of using the shorthant notation supported by the upstream library.

KevinAsher avatar Feb 01 '18 22:02 KevinAsher

You might want to check this pull request that was merged today https://github.com/Folkloreatelier/laravel-graphql/pull/281

dmongeau avatar Feb 02 '18 00:02 dmongeau

I'm not sure that's quite what he's asking for. I would actually like this as well. When defining args or fields, it'd be nice to have to only pass a type (Type::string()), instead of an array ['type' => Type::string()].

Thus,

'id' => Type::string(),

would be equivalent to

'id' => [
    'type' => Type::string(),
],

adamgoose avatar Feb 02 '18 06:02 adamgoose

@adamgoose, yep that's what I've meant.

KevinAsher avatar Feb 02 '18 12:02 KevinAsher

It's an easy workaround though, e.g.


public function fields()
    {
        $array = [
            'id'        => Type::nonNull(Type::string()),
            'email'     => Type::string(),
            'name'      => Type::string(),
            'posts'     => Type::listOf(GraphQL::type('Post')),
            'followers' => Type::listOf(GraphQL::type('User')),
            'followees' => Type::listOf(GraphQL::type('User'))
        ];

        $array = array_map(function($el) {
            if (is_array($el)) {
                return $el;
            }

            return [
                'type' => $el,
                'resolve' => [$this, 'resolveField']
            ];
        },$array);

        return $array;
    }
`

KevinAsher avatar Feb 18 '18 18:02 KevinAsher

Yes, I agree. While working with this gem, we need to write a lot of code, definitely comparing with graphql implementations of Rails. Would be great to decrease it a bit.

karensg avatar Feb 25 '18 20:02 karensg

Would not be better to take it directly from the models? $visible, $hidden, relations...

This could be somehow done writing some annotations on the models, routes and controllers. As nd approach to this, this library does it very good,

https://laravelcollective.com/docs/master/annotations

kikoseijo avatar Feb 26 '18 14:02 kikoseijo

Exactly, in that case we just need to define it once

karensg avatar Feb 26 '18 19:02 karensg