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

Make it possible to get arguments and field name #83

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

eiriksm
Copy link

@eiriksm eiriksm commented Nov 5, 2023

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
//    }
//  }
//}

@eiriksm
Copy link
Author

eiriksm commented Nov 5, 2023

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 :)

@wlouckx
Copy link

wlouckx commented Mar 14, 2024

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;

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

Successfully merging this pull request may close these issues.

None yet

2 participants