😵
GraphQLError(Variable 'a' has coerced Null value for NonNull type)
graphql-javaでGraphQLError(message=Variable 'variable' has coerced Null value for NonNull type)
が出るときは大体次の2パターンが原因。
- クエリ側の引数の宣言がnullableになっている
- 該当する引数が渡せていない
クエリ側の引数の宣言がnullableになっている
スキーマの宣言で引数がUserInput!
のようにnon-nullになっている場合、
extend type Mutation {
createUser(input: UserInput!) : User!
}
input UserInput {
name: string
}
クエリが次のようにUserInput
なっているとこのエラーが出る。
mutation CreateUser($input: UserInput) { // <- nullableで宣言してしまっている。
createUser(input: $input) {
id
}
}
UserInput!
で宣言すればOK。
該当する引数が渡せていない
Spring-Bootにおいて次のようにGraphQlのリクエストをしているとする。
import kotlinx.coroutines.withContext
import org.springframework.http.HttpEntity
import org.springframework.http.HttpMethod
import org.springframework.web.client.RestOperations
import org.springframework.web.client.exchange
import kotlin.coroutines.coroutineContext
data class GraphQlQuery(val query: String, val variables: Map<String, Any>?)
suspend fun post(url: String, restOperations: RestOperations, query: GraphQlQuery): String {
return withContext(coroutineContext) {
val response = restOperations
.exchange<String>(url, HttpMethod.POST, HttpEntity(query))
requireNotNull(response.body)
}
}
この時ついつい次のように書いてしまったりする。
post("https://...", restOperations,
GraphQlQuery("""
mutation CreateUser($input: UserInput!) {
createUser(input: $input) {
id
}
}
""",
mapOf("name" to "mike") // おや?
)
引数であるUserInputの型は次のようになっているので合っていそうな気もするが...
input UserInput {
name: string
}
実際はkey="input"でvalue=UserInputで入力してあげないといけない。
data class UserInput(val name: String)
post("https://...", restOperations,
GraphQlQuery("""
mutation CreateUser($input: UserInput!) {
createUser(input: $input) {
id
}
}
""",
mapOf("input" to UserInput("mike")) // Yes!
)
そんなまぬけな...と思うかもしれないが実際にハマってめっちゃ時間溶かしました。
Discussion