Experimental Subschema empty interface#5184
Conversation
Interfaces that are only reached via inline fragments on implementing types end up with missing or zero fields in the generated sub-schema. The snapshots capture the current (broken) behavior: - interface_empty_without_id: `interface Searchable` has zero fields - interface_only_inline_fragments: `interface Node` missing `createdAt` - interface_on_object_field: `interface FeedItem` missing `title` - interface_nested: `interface Event` missing `name`
Add a `backfill_empty_interfaces` option to UsedSchemaCollectionOptions. When enabled, after the IR walk completes, any interface that ended up with zero fields gets all its fields touched from the full schema. This handles the case where an interface is referenced as a return type (so it must exist in the sub-schema) but is only accessed via inline fragments on implementing types (so no fields were directly selected on it). Without this, the output contains `interface Foo` with no fields — invalid per the GraphQL spec. Interfaces that already have at least one field are left alone, so this only kicks in for the truly empty case. Enabled for experimental-regenerate-sub-schema.
|
Ah thank you for helping with this! However, this specific PR is flipping the purpose of SchemaSet on its head. SchemaSet is meant to produce intermediate, spec-invalid subsets, which we can combine/merge and individually evaluate. Only the merge of ALL subsets must produce a valid full schema (and even whether your exposed schema should be spec-valid is IMO debatable). We do already have some "fixing" capabilities in But I didn't put a ton of care into that, and we almost certainly could use a pulling-apart of what exactly we are fixing and breaking down each sub-fixing component then re-composing them into a specific "fix for this purpose" pipeline. So there's kind of three possible paths:
|
I think I'm convinced to do the same. Thanks for the response and detail |
In order to work out what part of our very large schema is actually being used by our products, we've been exploring using the subschema extraction. Our intent is to identify dead / unused schema and make our breaking changes detection & test selection more fine-grained (specific to the consuming product)
We've run into a problem of producing invalid schema.
schema
usage
output
which is invalid, since
Searchablehas no fields.Searchablebecause it appears as an output type ofQuery.search: Searchableand changing that would change the schema__typename(which is effectively what happens at runtime) because__is reservedThis PR implements a "fix": If we find empty interfaces, we force their fields existence (and hence their implementing concrete types to have those fields). This means we do have "unused fields", but only for these cases.
Not ideal, however this only occurs 12 times for us so is acceptable, and I expect it's not encountered in Meta's schema if it's not yet addressed.