craftcms / cms

Build bespoke content experiences with Craft.
https://craftcms.com
Other
3.28k stars 635 forks source link

GraphQL inline fragments not required? #7165

Open stereomyth opened 3 years ago

stereomyth commented 3 years ago

Description

In GraphQL I seem to be able to access custom fields on entries without inline fragments. Is this a bug or a feature?

Currently this query returns the correct data without error:

entries {
  customField
}

However as far as I can tell, the inline fragment should be required:

entries {
  ...on section_entrytype_Entry {
    customField
  }
}

While I think this is currently a bug, it is actually quite useful as the site has many entry types with shared custom fields which would result in a huge query similar but multiple times larger than:

entries {
  ...on section_entrytype1_Entry {
    customField1
    customField2
    customField3
  }
  ...on section_entrytype2_Entry {
    customField1
    customField2
    customField3
  }
  ...on section_entrytype3_Entry {
    customField1
    customField2
    customField3
  }
}

Additional info

andris-sevcenko commented 3 years ago

So this behavior depends on the devMode setting, as, enabling that, adds additional validation rules. If you enable devMode, you'll see the expected error.

This is because disabling devMode removes two validation rules from the GraphQL schema, both of which deal with the correct naming of fields. The reason for that being that they generate the full schema to check whether everything is named correctly and can be queried on the type, which involves some performance overhead.

I'll leave this open because we hope to make GraphQL schema cacheable eventually (#7222), at which point there would be no need to worry about this performance hit.

weotch commented 2 years ago

I do prefer the non-devMode behavior for the reasons that @stereomyth mentions. It allows me to make reusable fragments that use a generic type of EntryInterface which can be spread into multiple entry types that share a similar schema. Like:

# Used by the "Products" and "Bundles" sections
fragment productCard on EntryInterface {
  __typename
  sku
}

I actually came to this post while researching whether there was a config option for disabling those validation rules when running devMode.