発生したこと
GraphQLのString!型に空文字を送ったところ、スキーマに直接値を書き込む形では空文字のまま渡されるが、Variablesを使用して代入すると空文字がnullに変換される。
- スキーマ定義
type Mutation {
updateUser(id: ID! name: String!): User! @update
}
type User {
id: ID!
name: String!
}
- 単体のスキーマの場合。
- 正常に動作し、
name
は空文字のものが返される。
mutation {
updateUser(
id: 1
name: ""
) {
id
name
}
}
- Variablesを使用してスキーマを使用した場合。
- こちらでは
updateUser
でname
にnullのリクエストを投げているというエラーが出る。
mutation UpdateUser(
$id: ID!
$name: String!
) {
updateUser(
id: $id
name: $name
) {
id
name
}
}
{
"id": 1,
"name": ""
}
環境
PHP: 7.2
Laravel: 6.2
Lighthouse: 4.11
原因
Lighthouseではリクエストのquery
やmutation
といったスキーマの集合を一旦Laravelのリクエストとして受け取ってから引数の代入や個別のスキーマ毎に分解して処理を行っている。
その際にVariableを使用していると、それぞれのスキーマの引数に入れる際にLaravelのリクエストとして処理されてしまうため、グローバルミドルウェアのConvertEmptyStringsToNull
が反応してしまい空文字がnullへと変換されていた。
解決方法
Kernel
のConvertEmptyStringsToNull
をコメントアウトなり削除なりする。
class Kernel extends HttpKernel
{
protected $middleware = [
// コメントアウトする
// \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
最後に
原因がわかればなんてことはないエラーなのですが、面倒だからと直接クエリを書き換えて動作確認してたりするとなかなか気がつかない問題です。
エラーメッセージでもLighthouseで「String!にnullが送られてきている」みたいなものしか出なくて調査するのに結構手間取りました。