glesys / butler-graphql

An opinionated GraphQL package for Laravel.
MIT License
34 stars 5 forks source link

Mix SDL and GraphQL PHP Types #34

Open mathieutu opened 3 years ago

mathieutu commented 3 years ago

Hi, it's me again! Sorry to bother you with my noob questions, but I'm trying to add types to the schema from php, and I didn't find any way to do that.

Could you help on that?

Thanks.

wecc commented 3 years ago

To add types you just create them in your schema, like so:

type Query {
    things: [Thing!]!
}

type Thing {
    name: String!
}

Then define a resolver for the query:

namespace App\Http\Graphql\Queries

class Things
{
    public function __invoke($root, $args, $context)
    {
        return [
            ['id' => 'thing-1'],
            ['id' => 'thing-2'],
        ];
    }
}

And finally a resolver for the Thing type:

namespace App\Http\Graphql\Types;

class Thing
{
    public function name($source, $args, $context, $info)
    {
        return "This is " . $source['id'];
    }
}

Hope this helps! If not, send me a DM on Twitter and I'll be happy to arrange a call or something.

(As you can see, the resolvers don't really care what you throw at them, as long as you give them something they know how to resolve. Eloquent Models, arrays, whatever you return from the "level above" will be the $source in all resolvers "below".)

mathieutu commented 3 years ago

Hi, thanks for the help, and your proposal. It is very kind of you.

Actually it was not what I had in mind.

I'm totally ok the resolver concept, but I'm trying to add some new types to the shema, with php, via the Graphql-php api. So, merge scheme from SDL and PHP objects.

For example:


$userType = new ObjectType([
    'name' => 'User',
    'description' => 'Our blog visitor',
    'fields' => [
        'firstName' => [
            'type' => Type::string(),
            'description' => 'User first name'
        ],
        'email' => Type::string()
    ]
]);

The goal is to construct some fields dynamically from constants or info in the project, or by batch for similar types with little difference (where or orderBy clauses for example).


no linked at all, but it can interest you: I've made some poc about pluging the graphql api directly to eloquent models, with automatic relations eagerloading, select, queries clauses, order, etc. and actually it works pretty well. I define just the root queries, and everything else is handled automatically in optimised way...

wecc commented 3 years ago

Ah, sorry, I misunderstood.

Dynamically extending the schema using PHP is not a use-case I'm familiar with using butler-graphql but since we do use https://github.com/webonyx/graphql-php as the underlying engine I guess anything is possible :)

There does seem to be a SchemaExtender (tests) that might be useful or at least work as inspiration on how to extend an existing schema.

If necessary we can look into adding additional hooks in HandlesGraphqlRequests that allows for this kind of flexibility.

Please keep us updated with your findings, it's an interesting feature :)

mathieutu commented 3 years ago

ok thanks, I did not find SchemaExtender in their doc, thanks for the tip, I'll dig around that..

mathieutu commented 3 years ago

Hi, I've made some tests and try, but actually the SchemaExtender is not really made for that (it's mainly for the usage of extend keyword in sdl).

Instead I generate SDL from php types via a command. Only scalar types should be added via php, and I do it with decorateTypeConfig.

If you want to give a look to what I achieve, you can see the project (just a dumb demo) here: https://github.com/mathieutu/pingcrm-graphql/tree/master/app/Http/Graphql

Please feel free to let me know what you think about it!

wecc commented 3 years ago

Very interesting... :) It should be possible to override the decorateTypeConfig defined in HandlesGraphqlRequests already, but the "append stuff to a Schema instance" hook (that you mention in https://github.com/glesys/butler-graphql/pull/33#issuecomment-727050189) is missing.