Generated fields aren't matching what I have defined in my entity

852 Views Asked by At

I am creating a Kotlin Spring-Boot api with a GraphQL interface. I am facing an issue when accessing one of my entities through GraphQL. Below you can most of my setup for accessing the user object.

The issue is coming from the generated fields in GraphQL, it isn't matching what I have defined in my entity. This is only happening on the field isAdmin (and similarly styled ones). The output gets changed to admin and I cannot access it as isAdmin. It's not happening if I name the field like inAdmin, letAdmin or even admin. Its a very vague problem and I cannot seem to find any documentation on it.

@Entity
@Table(name = "User")
class User(

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    var id: Long,

    @Column(name = "user_type")
    var type: String,

    @Column(name = "is_admin")
    var isAdmin: Boolean
)

Resolver implementation for returning all users

@GraphQLApi
@Component
class UserResolver {
    @Autowired
    lateinit var userService: userServiceInterface

    @GraphQLQuery()
    fun getUsers(): List<UserType> {
        return userService.getUsers()
    }
}

Service Interface for storing custom queries

interface userServiceInterface {
    fun getUsers(): List<User>
}

GraphQL gui output schema

user{
    id
    type
    admin //<-- invalid, expecting isAdmin
}

Edit: A workaround right now is to use alias

user{
    id
    type
    isAdmin: admin
}
2

There are 2 best solutions below

1
On

In spring, all variables like isSomething are replaced by something in the json.

To make it explicit, you can use a @JsonProperty annotation

Your class will be

@Entity
@Table(name = "User")
class User(

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    var id: Long,

    @Column(name = "user_type")
    var type: String,

    @JsonProperty("isAdmin")
    @Column(name = "is_admin")
    var isAdmin: Boolean
)

I am not sure why it happens. I'll look for the answer and edit the post when I find.

0
On

By default, all JavaBean properties are named by their property name, not their accessor name. So getSomething will get mapped as something and isAdmin (that returns a boolean) will get mapped as admin. This is in line with the behavior of most frameworks/languages/serialization formats. You'll get the same default behavior when mapping to JSON, accessing the field via SpEL, mapping to DB column names etc.

To override the name on case-by-case basis, add @GraphQLQuery to the field (affects both input and output types) or accessor/getter (affects output types only). To affect the input type only add @GraphQLInputField on the field or mutator/setter. @JsonProperty is also respected for input types, and can optionally be configured for outputs.

You can also globally configure the naming strategy. Will post an example later.