sgqlc icon indicating copy to clipboard operation
sgqlc copied to clipboard

add GraphQL named fragment support

Open barbieri opened this issue 7 years ago • 7 comments

Support for named fragments as below:

query {
   node(id: "some-id") {
      ... UserLogin
   }
}
fragment UserName on User {
   login
}

barbieri avatar Jan 17 '18 17:01 barbieri

Most of the infrastructure for fragments is in to implement inline fragments, it solves most of the usage.

The named fragments could be used to save some bandwidth, sending that part only once.

barbieri avatar Feb 24 '19 16:02 barbieri

Hello! Fragments like this is not supporded yet?

SShatun avatar Mar 11 '19 12:03 SShatun

no, this is the named fragments I wrote above... do you have a great use case for them?

the way I see is that they help to write manual GraphQL, to avoid repetition... and also save some bandwidth in the query.

the repetition problem is easy to solve in python, since you just write a Python function that selects the fields for you.

however the bandwidth is not solvable without named fragments

barbieri avatar Mar 11 '19 13:03 barbieri

Now I ran into a problem of code repetition. I work with huge queries and most of them have repeatable parts. Now I dealing with it like this:

client = self.op.client(client_id=str(client_id))
orders = client.orders(date=datetime.now() - timedelta(weeks=1))
orders.items.items_info.time_table(
    date_from=(week_ago,
    date_to=datetime.now())
orders.__fields__()
orders.items.items_info.__fields__()
orders.items.__fields__()

client.last_order.items.items_info.time_table(date_from=week_ago,
                                                    date_to=datetime.now())
client.last_order.items.items_info.__fields__()
client.last_order.items.__fields__()
client.last_order.__fields__()
client.phones_list(from_=0, to=999)
client.__fields__()

orders and last_order are same graphql types. And it is used in other queries too. Is there better way generate queries like this?

SShatun avatar Mar 11 '19 15:03 SShatun

not ideal, but you can avoid the verbosity with:

def select_order_fields(parent_selection):
   parent_selection.items.items_info.time_table(
    date_from=(week_ago,
    date_to=datetime.now())
   parent_selection.__fields__()
   parent_selection.items.items_info.__fields__()
   parent_selection.items.__fields__()

select_order_fields(orders)
select_order_fields(client.last_order)

barbieri avatar Mar 11 '19 16:03 barbieri

It is looks better. Thank you! Is there the way to avoid writting __fields__() all the time? In case if I need full query every time? And one more quastion) How to solve the problem when fields has different names but same type? Is there the way to select nested fields anyway?

SShatun avatar Mar 12 '19 07:03 SShatun

We do have the "auto selection" to generate the __to_graphql__(), but it's more for printing, not adding to the actual selection.

If you think it's useful I can expose that to __fields__(), something like __fields__(..., __recursive__=True) or __recursive__=<depth>.

barbieri avatar Mar 12 '19 16:03 barbieri