Skip to content

Is there a way to export gql response dynamicly? #301

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

Closed
nrbnlulu opened this issue Feb 22, 2022 · 5 comments
Closed

Is there a way to export gql response dynamicly? #301

nrbnlulu opened this issue Feb 22, 2022 · 5 comments
Labels
type: question or discussion Issue discussing or asking a question about gql

Comments

@nrbnlulu
Copy link

nrbnlulu commented Feb 22, 2022

The problem:

exporting data with graphql is inefficient .
for example lets look at this query:

query{
  SiteById(id:852){
    unitSet{
      connableSet{
        connablealertSet{
        TidKey
        TidValue
        }
      }
    }
  }
}

returns this json respons:

{
  "SiteById": [
    {
      "unitSet": [
        {
          "connableSet": [
            {
              "connablealertSet": [
                { "TidKey": 151, "TidValue": "סכום בדיקת ROM שגוי" }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Lets assume i only need TidKey and TidValue,
to do this this is what you would normally find on the web:

import pandas as pd
pd.json_normalize(res['SiteById'][0]['unitSet'][0]['connableSet'][0]['connablealertSet'])

Results this:
image

As you can see this is extremely inefficient for these reasons:

  1. I need to know exactly what i queried for.
  2. If the result had more fields the code above would break .
  3. If i would change the query slightly i would need to change how i export it as well.

I hope i am missing something because otherwise its back to REST

@leszekhanusz leszekhanusz added the type: question or discussion Issue discussing or asking a question about gql label Feb 22, 2022
@leszekhanusz
Copy link
Collaborator

1. I need to know exactly what i queried for.

??? You need to know what you queried for to parse data for any query language, be it GraphQL, REST, SQL or anything else.

2. If  the result had more fields the code above would break .

Then you may need to post-process your result. As a GraphQL result is returned in json format, you can use something like jsonpath

3. If i would change the query slightly i would need to change how i export it as well.

Same with REST

@nrbnlulu
Copy link
Author

nrbnlulu commented Feb 22, 2022

1. I need to know exactly what i queried for.

??? You need to know what you queried for to parse data for any query language, be it GraphQL, REST, SQL or anything else.

Of course, but my expectations is that gql will supply an client API to retrieve exactly what you need,
after all you asked the query so you should know what the fields would be.
In the example above pseudo code would be:

>>> res.TidKey
151
>>> res.TidValue
סכום בדיקת ROM שגוי
2. If  the result had more fields the code above would break .

Then you may need to post-process your result. As a GraphQL result is returned in json format, you can use something like jsonpath

Thanks this might be what i am looking for, but still would be nice to have an API as stated above

@leszekhanusz
Copy link
Collaborator

leszekhanusz commented Feb 22, 2022

Other options:

  • use REST for some common queries in conjunction with GraphQL for more complex queries
  • add a shortcut in your GraphQL schema to directly provide what you need (ie. add a new AllTIDs root query field)

@leszekhanusz
Copy link
Collaborator

You might be interested in this blog post explaining the flat chain syntax proposal even though it will probably never be added in the GraphQL spec as it was proposed 6 years ago...

@nrbnlulu
Copy link
Author

nrbnlulu commented Mar 12, 2022

Thanks for the concern!
I will look into it, as for now i have created a query data class and all my requests returns that type.
the class looks like this:

@dataclass
class QueryType:
    @dataclass
    class Error:
        message:str=""
        code:str=""
    query:str
    receiver:qtc.Signal # (I'm using Qt for my GUI so the query is executed in another thread and  result is emitted with a signal) 
    res: 'typing.Any' = None
    flags:list= dataclasses.field(default_factory=list)
    jpath:str="$"
    success_jpath:str="$.*.success"
    errors_jpath:str="$.*.errors.nonFieldErrors[*]"
    count:int=0
    errors:ErrorType=Error()
    success:bool=False
    """number of times this query beed execudted in the server"""

    def __repr__(self) -> str:
        def P(obj):return pprint.pformat(obj,indent=3)
        return f"""
        query is->: {P(self.query)}\n
        reciver is->: {self.receiver}\n
        jpath is->: {self.jpath}\n
        result is->: {P(self.res)}\n
        flags are->: {P(self.flags)}\n
        version is->: {P(self.count)}
        etc...
        """

Then i just create a constants class with all the override properties from the QueryType class
and send it further to the gql client class to execute it and set all the properties by the jpathes and flags provided.
This allows me to access the data more easily and make less mistakes.

if ill have time in the future i intend to make a class that creates data-classes dynamically by the type of the return items
i.e dict will be evaluated as a class and string and other types as fields and so on but i think it will be way more complicated then this due duplicated keys in gql responses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question or discussion Issue discussing or asking a question about gql
Projects
None yet
Development

No branches or pull requests

2 participants