|
| 1 | +# RFC: Schema Fragments |
| 2 | + |
| 3 | +## Problem |
| 4 | + |
| 5 | +When writing large schemas, there is no way to reuse similar fields between `ObjectTypeDefinition`(s) and `InputValueDefinition`(s). One can use [interfaces](https://spec.graphql.org/June2018/#sec-Interfaces) to enforce that particular fields are implemented, though this doesn't really help, as a schema creator I still have to repeat X fields on X amount of types. |
| 6 | + |
| 7 | +Below I have `Users`(s) and `Post`(s) and where both types have the following properties; `id`, `createdAt` and `updatedAt`: |
| 8 | + |
| 9 | +```graphql |
| 10 | +type User { |
| 11 | + id: ID # Repeated |
| 12 | + createdAt: DateTime # Repeated |
| 13 | + updatedAt: DateTime # Repeated |
| 14 | + name: String |
| 15 | +} |
| 16 | + |
| 17 | +type Post { |
| 18 | + id: ID # Repeated |
| 19 | + createdAt: DateTime # Repeated |
| 20 | + updatedAt: DateTime # Repeated |
| 21 | + content: String |
| 22 | +} |
| 23 | +``` |
| 24 | + |
| 25 | +> Notice how the three properties are repeated. |
| 26 | + |
| 27 | +As mentioned, you can use interfaces here, so for example a `BaseInterface` that contains the properties, and then this is implemented on each type: |
| 28 | + |
| 29 | +```graphql |
| 30 | +interface BaseInterface { |
| 31 | + id: ID # Repeated |
| 32 | + createdAt: DateTime # Repeated |
| 33 | + updatedAt: DateTime # Repeated |
| 34 | +} |
| 35 | + |
| 36 | +type User implements BaseInterface { |
| 37 | + id: ID # Repeated |
| 38 | + createdAt: DateTime # Repeated |
| 39 | + updatedAt: DateTime # Repeated |
| 40 | + name: String |
| 41 | +} |
| 42 | + |
| 43 | +type Post implements BaseInterface { |
| 44 | + id: ID # Repeated |
| 45 | + createdAt: DateTime # Repeated |
| 46 | + updatedAt: DateTime # Repeated |
| 47 | + content: String |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +However, this isn't helpful at scale because your still repeating each field. |
| 52 | + |
| 53 | +## Solution |
| 54 | + |
| 55 | +Enable the usage of fragments on `ObjectTypeDefinition`(s) and `InputValueDefinition`(s) to reduce the repetition of common fields. |
| 56 | + |
| 57 | +Below I have `Users`(s) and `Post`(s) and where both types have the following properties; `id`, `createdAt` and `updatedAt`. The listed properties are only defined once and I use the fragment spread syntax to apply them to each type: |
| 58 | + |
| 59 | +```graphql |
| 60 | +fragment BaseInterface on ObjectTypeDefinition { |
| 61 | + id: ID |
| 62 | + createdAt: DateTime |
| 63 | + updatedAt: DateTime |
| 64 | +} |
| 65 | + |
| 66 | +type User { |
| 67 | + ...BaseInterface |
| 68 | + name: String |
| 69 | +} |
| 70 | + |
| 71 | +type Post { |
| 72 | + ...BaseInterface |
| 73 | + content: String |
| 74 | +} |
| 75 | +``` |
| 76 | + |
| 77 | +## Implementation |
| 78 | + |
| 79 | +I assume that the GraphQL parser would need to be adapted to allow the usage of fragments on the fields, and then I see it being something that your tool should implement similar to how interfaces are enforced. |
0 commit comments