php-graphql-client
php-graphql-client copied to clipboard
Make it possible to get arguments and field name
Thanks for this library. For me it's super important to represent the query as an object, and this library seems to do the trick nicely. However, it's missing 2 things I need, which this PR adds:
A getter for field name and a getter for arguments.
First. Here is a simple program to illustrate why I want a getter for arguments:
<?php
require_once __DIR__ . '/vendor/autoload.php';
$gql = (new \GraphQL\Query('things'))
->setArguments([
'someClientId' => 'someValueBasedOnCodebase'
]);
echo (string) $gql;
// This prints:
// query {
//things(someClientId: "someValueBasedOnCodebase")
//}
// Response is queued and serialized and deserialized, and now all I have back
// is the query object and a cursor id, and I want to just append some arguments
// to it.
$cursor_id = 'someCursor';
$new_args = $gql->getArguments();
$gql->setArguments(array_merge($new_args, [
'after' => $cursor_id
]));
echo (string) $gql;
// With this PR this prints:
// query {
//things(someClientId: "someValueBasedOnCodebase" after: "someCursor")
//}
And here is why I want the getter for field name:
<?php
require_once __DIR__ . '/vendor/autoload.php';
$gql = (new \GraphQL\Query('things'))
->setSelectionSet([
'id',
'name',
(new \GraphQL\Query('subThings'))
->setArguments([
'filter' => 'providerId123',
])
->setSelectionSet([
'id',
'name'
])
]);
echo (string) $gql;
// This prints:
// query{
// things {
// id
// name
// subThings(filter: "providerId123") {
// id
// name
// }
// }
//}
// Well that's all good. But what if I have 20 customers, and they all use the
// library I wrote to retrieve "things", but they have maybe different provider
// ids, and maybe even different fields they want to select. How about doing it
// like this in just a custom override for those where I need it:
$sets = $gql->getSelectionSet();
foreach ($sets as $set) {
if (!$set instanceof \GraphQL\Query) {
continue;
}
$name = $set->getFieldName();
if ($name !== 'subThings') {
continue;
}
$set->setArguments(['filter' => 'providerId456']);
$set->setSelectionSet(array_merge($set->getSelectionSet(), [
'someField',
'someOtherField'
]));
}
echo (string) $gql;
// With this PR applied, this now is possible and prints:
// query {
// things {
// id
// name
// subThings(filter: "providerId456") {
// id
// name
// someField
// someOtherField
// }
// }
//}
I'm torn between trying to follow the style in the test class here and the feedback from CI systems, so I will just say that this seems to be good enough, and close enough to the initial code style :)
Especially the fieldname getter interests me as well. It would allow me to implement a simple generic pagination method by extracting the fieldname so I can do something like
$fieldName = $query->fieldname;
$items = $client->runQuery($query)->getResults();
$hasNextPage = $items->data->$fieldName->pageInfo->hasNextPage;
$after = $items->data->$fieldName->pageInfo->endCursor;