Skip to content

Support for both constructor and setter argument binding #1163

Closed
@desiderati

Description

@desiderati

If you have defined a class with some properties in the constructor and other properties being accessed via setter methods, only one of these (either the constructor or the setters) will be mapped.

data class TestObject(
    val name: String
) {
    var cellphone: String = ""
}

@Controller
class TestResolver {
    @MutationMapping
    fun createTestObject(
        @Argument testObject: TestObject
    ) {
        println(testObject.cellphone) // Will be empty
    }
}
input TestObjectInput {
    name: String!
    cellphone: String!
}

type Mutation {
    createTestObject(testObject: TestObjectInput!)
}

schema {
    mutation: Mutation
}

mutation createTestObjectWithoutValidation($testObject: TestObjectInput!) {
    createTestObjectWithoutValidation(testObject: $testObject)
}

{
  "testObject": {
    "name": "Felipe",
    "cellphone": "(41) 98765-4321"
  }
}

The issue arises because, in line 260 of the GraphQlArgumentBinder class, if the type object has a constructor with at least one argument, the binder uses that constructor to map the properties. If not, it defaults to using the setter methods to populate them. The idea with Kotlin is that you can create a data class with a primary constructor, where properties are used in equals() and hashCode(), but other properties, like the 'cellphone' property mentioned above, may not be. So, why not support both approaches, populate them via a constructor and setters?

GraphQlArgumentBinder.java
...
Constructor<?> constructor = BeanUtils.getResolvableConstructor(targetClass);

Object value = (constructor.getParameterCount() > 0) ?
    bindMapToObjectViaConstructor(rawMap, constructor, targetType, bindingResult) :
    bindMapToObjectViaSetters(rawMap, constructor, targetType, bindingResult);
...

Version: Spring GraphQL 1.3.1

Thanks, Felipe

Metadata

Metadata

Assignees

Labels

in: dataIssues related to working with datatype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions