Skip to content

GraphQlArgumentBinder silently drops fields from extended input types for nested input objects #1418

Description

@salbecknm

Description

Spring GraphQL correctly accepts and validates GraphQL input type extensions (extend input) at schema level.
However, when an extended input type is used nested inside another input object, the additional fields introduced by the extension are silently dropped during runtime binding.
This results in GraphQL input that is:

  • valid according to the schema,
  • but partially inaccessible from Java code.

This behavior makes input extensions effectively unusable for nested input types.

Actual Behavior

Given the following schema:

input AddressInput {
  street: String
}

extend input AddressInput {
  zipCode: String
}

input UserInput {
  name: String
  address: AddressInput
}

type Mutation {
  createUser(input: UserInput!): Boolean
}

And Java models:

class AddressInput {
  private String street;
}

class ExtendedAddressInput extends AddressInput {
  private String zipCode;
}

class UserInput {
  private AddressInput address;
}

Executing the mutation:

mutation {
  createUser(input: {
    name: "John",
    address: {
      street: "Main St",
      zipCode: "12345"
    }
  })
}

then the following occurs

  • Schema validation succeeds.
  • Execution proceeds without errors.
  • At runtime, UserInput.address is always bound as AddressInput.
  • The zipCode field is silently ignored and cannot be accessed.
  • No error or warning is raised.

Reproduction

A minimal Maven project ZIP is attached. To reproduce:

spring-graphql-input-extension-demo.zip

  1. Import the project
  2. Run the test GraphQlInputExtensionTest
  3. The test fails, demonstrating that a field defined via extend input is accepted by the schema but not bound to the Java input object at runtime.

Current workaround:
I implemented a local workaround that makes the extended input fields available at runtime, which confirms that the issue is confined to argument binding.
The workaround requires replacing internal framework classes and is therefore not suitable as a long-term solution.
I can provide details of the workaround, including the implementation, if that would be helpful.

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions