😵

GraphQLError(Variable 'a' has coerced Null value for NonNull type)

2020/12/28に公開

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