Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Support empty composite types #606

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions spec/Section 3 -- Type System.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ type Query {
}
```

Note: A `query` root operation type which does not define any fields still
allows for [Schema Introspection](#sec-Schema-Introspection).

Similarly, the following mutation is valid if a `mutation` root operation type
has a field named "setName". Note that the `query` and `mutation` root types
must be different types.
Expand Down Expand Up @@ -792,8 +795,7 @@ Objects are never valid inputs.
Object types have the potential to be invalid if incorrectly defined. This set
of rules must be adhered to by every Object type in a GraphQL schema.

1. An Object type must define one or more fields.
2. For each field of an Object type:
1. For each field of an Object type:
1. The field must have a unique name within that Object type;
no two fields may share the same name.
2. The field must not have a name which begins with the
Expand All @@ -804,8 +806,8 @@ of rules must be adhered to by every Object type in a GraphQL schema.
characters {"__"} (two underscores).
2. The argument must accept a type where {IsInputType(argumentType)}
returns {true}.
4. An object type may declare that it implements one or more unique interfaces.
5. An object type must be a super-set of all interfaces it implements:
2. An object type may declare that it implements one or more unique interfaces.
3. An object type must be a super-set of all interfaces it implements:
1. The object type must include a field of the same name for every field
defined in an interface.
1. The object field must be of a type which is equal to or a sub-type of
Expand Down Expand Up @@ -1052,8 +1054,7 @@ Interfaces are never valid inputs.

Interface types have the potential to be invalid if incorrectly defined.

1. An Interface type must define one or more fields.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting discussion around this point specifically:

#236

This also drives the requirement that Interfaces must define at least one field - otherwise the Interface would not actually describe a contract to be fulfilled. This concept of contract-less interfaces is often called "marker interfaces" and in my opinion (hopefully not an uncommon opinion) are a bad practice borrowed from limited object-oriented languages.
-- @leebyron


I'm personally in favour of field-less interfaces as a placeholder for adding shared fields later. E.g. you might say that 3 different types are Searchable and in future you may require that they have name and url in common so that you can display them in a search results page even if you don't have specific handling for some of the concrete types, but when you start designing your schema you might not know what those "Searchable" shared fields are/should be named yet.

I also think this can be useful for interfaces that implement other interfaces:

interface Searchable implements Node {}

e.g. to say that everything that's searchable is a Node, but not everything that's a Node is searchable.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the latest from the transitive interface implementation RFC

interface Searchable implements Node {}

would actually be an error, unless Node itself did not have a contract with any fields. implements instead of extends is intentional here, so Searchable would have to implement (declare) all fields Node's contract requires.

2. For each field of an Interface type:
1. For each field of an Interface type:
1. The field must have a unique name within that Interface type;
no two fields may share the same name.
2. The field must not have a name which begins with the
Expand Down Expand Up @@ -1402,16 +1403,17 @@ Literal Value | Variables | Coerced Value
`$var` | `{ var: "abc123" } }` | Error: Incorrect value
`{ a: "abc", b: "123" }` | `{}` | Error: Incorrect value for field {b}
`{ a: "abc" }` | `{}` | Error: Missing required field {b}
`{ b: $var }` | `{}` | Error: Missing required field {b}.
`{ b: $var }` | `{}` | Error: Missing required field {b}
`{ }` | `{}` | Error: Missing required field {b}
`$var` | `{ var: { a: "abc" } }` | Error: Missing required field {b}
`$var` | `{ var: { } }` | Error: Missing required field {b}
`{ a: "abc", b: null }` | `{}` | Error: {b} must be non-null.
`{ b: $var }` | `{ var: null }` | Error: {b} must be non-null.
`{ b: 123, c: "xyz" }` | `{}` | Error: Unexpected field {c}

**Type Validation**

1. An Input Object type must define one or more input fields.
2. For each input field of an Input Object type:
1. For each input field of an Input Object type:
1. The input field must have a unique name within that Input Object type;
no two input fields may share the same name.
2. The input field must not have a name which begins with the
Expand Down
2 changes: 2 additions & 0 deletions spec/Section 4 -- Introspection.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ identify which actual type of the possible types has been returned.

This field is implicit and does not appear in the fields list in any defined type.

Note: The `__typename` field can always be queried, even if an Object or Interface does not define any fields.


## Schema Introspection

Expand Down