Skip to content

Allow empty input object types - #1249

Open
DaleSeo wants to merge 2 commits into
graphql:mainfrom
DaleSeo:empty-input-objects
Open

DaleSeo wants to merge 2 commits into
graphql:mainfrom
DaleSeo:empty-input-objects

Conversation

@DaleSeo

@DaleSeo DaleSeo commented Oct 28, 2026 •

Copy link
Copy Markdown

Follow up to:

Today, an input object type must define at least one input field. This proposal removes that requirement, making input Filter {} a valid definition. The goal is to bring this to the Nov 5 Working Group as RFC 1.

The motivation comes from the Schema Search RFC (graphql/ai-wg#187). It describes a service that returns a valid subset of its schema as SDL in response to a natural language query. That subset may need to include an input object required by an operation, even when the query does not involve any of its fields:

type Query {
  issues(filter: IssueFilter!): [Issue!]!
}
input IssueFilter {}
type Issue {
  title: String!
}

Under the current rule, the slicer has to either drop the issues field, hiding the entry point, or keep an arbitrary input field. This change lets the slice retain the reference and allows the model to request IssueFilter later.

It also removes one more reason a schema with all deprecated elements removed can become invalid, as mentioned in #1228 (comment).

GraphQL.js implementation: graphql/graphql-js#4923, graphql/graphql-js#4934

@netlify

netlify Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for graphql-spec-draft ready!

Name Link
🔨 Latest commit c3783da
🔍 Latest deploy log https://app.netlify.com/projects/graphql-spec-draft/deploys/6ae354eb6b058853340afa93
😎 Deploy Preview https://deploy-preview-1249--graphql-spec-draft.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread spec/Section 3 -- Type System.md Resolved
Comment thread spec/Section 3 -- Type System.md Resolved
@benjie

benjie commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

When thinking about what can be left out of an input type, all required fields must be retained. Consider:

input Foo {
  a: Int
  b: Int!
  c: Int = 1
  d: Int! = 1
  e: [Int!]
  f: [Int!]! = []
}

this could compress down to:

input Foo {
  b: Int!
}

but representing it as an empty input object would be invalid, a value could not be fed to that argument that the underlying schema (with all the input fields) would accept.


(Solved: feedback on PR description)

Incidentally the argument around your example:

type Query {
  issues(filter: IssueFilter): [Issue!]!
}

Under the current rule, the slicer has to either drop the issues field, hiding the entry point, or keep an arbitrary input field.

doesn't quite hold because it can be mapped by dropping the filter argument:

type Query {
  issues: [Issue!]!
}

Maybe you meant issues(filter: IssueFilter!): [Issue!]!?

Comment thread spec/Section 3 -- Type System.md Resolved
Comment thread spec/Section 3 -- Type System.md Resolved
Comment thread spec/Section 3 -- Type System.md Resolved
Comment thread spec/Section 3 -- Type System.md Outdated
Comment on lines +1586 to +1596
An Input Object type may define no input fields. This may be written with an
empty set of braces, or by omitting the braces entirely; the following two
definitions are equivalent:

```graphql example
input Empty {}
```

```graphql example
input Empty
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

IIRC1, Lee has expressed a preference that we distinguish these for other types; mapping to input objects:

# Valid empty input object type
input Empty {}

# Declared but incomplete input type - awaiting field declarations
input Empty

With this, you might also need to allow input extensions to contain * rather than + fields.

Footnotes

  1. My memory of this is hazy though, so I'll need to go back through the notes/videos to see exactly what was said. ↩

@DaleSeo DaleSeo Oct 29, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Lee's comment in #1228 (comment) and PR #1245 got me thinking that we should allow {} as well, not {} only. 😅

Now I realize my reading was wrong. I've dropped the "equivalent" sentence and the braceless example, and taken your validation wording.

The same question applies to the sibling PRs, so I left notes there to make sure all three line up.

@martinbonnin martinbonnin Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

With this, you might also need to allow input extensions to contain * rather than + fields.

@benjie can you ellaborate? Since InputObjectExtensions reuses the InputFieldDefinitions grammar rule, both input definitions and extensions should have *?

InputObjectTypeExtension :
- extend input Name Directives[Const]? InputFieldsDefinition
- extend input Name Directives[Const] [lookahead != `{`]

InputFieldsDefinition : { InputValueDefinition\* } // * proposed in this PR

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I said "might" because I didn't check the grammar rules for extensions and wasn't sure if they might still use + via a different mechanism (e.g. I didn't check if they did extend input Name Directives[Const]? { InputValueDefinition+ }). Since they use the same grammar rule that has already been adjusted, InputFieldsDefinition, no action necessary.

@benjie

benjie commented Oct 29, 2026

Copy link
Copy Markdown
Member

I think something went wrong with GitHub, some of the comments from my review posted but others remained "pending". I've submitted the review again, but now it looks like there might be duplicates... I'm not going to delete them in case that causes more headaches 😅

@DaleSeo

This comment was marked as resolved.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants