yuki24/artemis

Add support for GraphQL Fragments

yuki24 opened this issue · 5 comments

Add support for GraphQL Fragments

Unless there's already some standard that I'm not aware of, I think it would be cool to have something like this:

app/operations/metaphysics/
  - _order.graphql
  - approve_order.graphql
  - order.graphql

That first file would be a fragment by virtue of it's filename starting with an underscore - just like partials in Rails views. So approve_order.graphql and order.graphql could then reference the fragment with that name and I'd be able to reduce the boilerplate.

Does that seem doable? Did you have another thought here?

I really like this idea. I’ll spike on it and see how it goes.

So basic Fragment support is actually already in as the graphql-client gem resolves the Ruby constant name as a GraphQL fragment:

# app/operations/metaphysics/order_fragment.graphql
fragment on Order {
  state
}
# app/operations/metaphysics/order.graphql
query($id: String!) {
  ecommerceOrder(id: $id) {
    id
    ...Metaphysics::OrderFragment
  }
}
Metaphysics::Order.document.to_query_string
# => query Metaphysics__Order($id: String!) {
#      ecommerceOrder(id: $id) {
#        id
#        ...Metaphysics__OrderFragment
#      }
#    }
#
#    fragment Metaphysics__OrderFragment on Order {
#      state
#    }

But I like the _ convention as it's very explicit and will help organize *.graphql files. The Ruby constant syntax above also breaks editor extensions as it's invalid in the standard GraphQL. By adding the _ convention we will be able to keep everything syntactically correct as well as a lot more benefits it can possibly provide.

Whoa, nice! I'm going to extract that fragment as you've shown here over on Volt and if/when it makes sense for the partial-style we can move to that too. Thanks!!

Now files formatted in _*_fragment can be looked up as a fragment. The fragment suffix was added to avoid naming conflict with a normal query file:

app/operations/metaphysics/
  - _order_fragment.graphql
  - approve_order.graphql
  - order.graphql

The notable difference between normal queries and fragments is that the dynamix finder doesn't resolve fragments but fragments can be looked up as a constant:

Metaphysics.approve_order   # => makes a mutation request
Metaphysics.order           # => makes a query request
Metaphysics.order_fragment  # => NoMethodError
Metaphysics._order_fragment # => TypeError

Metaphysics::ApproveOrder   # => returns a mutation
Metaphysics::Order          # => returns a query
Metaphysics::OrderFragment  # => returns a fragment
Metaphysics::_OrderFragment # => NameError