バージョン2.0.14からrails generate graphql:install
した時に生成されるapp_schema.rb
にvalidate_max_errors(100)
が追加されるようになりました。
下記がその時のCHANGELOGです。
関連する差分は下記です。[プルリク]
+
+ # Stop validating when it encounters this many errors:
+ validate_max_errors(100)
end
上記の変更により、バージョン2.0.14から使い始めてた場合はvalidate_max_errors
が自動的に設定されているのですが、それ以前から使っている場合は自主的に設定しない限りvalidate_max_errors
は設定されていません。
もしvalidate_max_errorsを設定していない場合、ほとんどの場合は設定した方が良いので紹介するためにこの記事を書くことにしました!
validate_max_errorsを設定すると何が嬉しいのか?
graphql-rubyでは、argumentsにエラーがある場合でも全てのargumentsを検証してからエラーを返却します。
例えば、idの配列をargumentsに指定してbook_typeのconnectionを返却するクエリーを考えます。
query Books($ids: [Int!]!) {
books(ids: $ids) {
nodes {
id
}
}
}
これに下記のvariablesを指定します。
{
"ids": ["a", "b", "c"]
}
結果は下記のようにargumentsの全エラーがerrors
に設定されて返却されます。
{
"errors": [
{
"message": "Variable $ids of type [Int!]! was provided invalid value for 0 (Could not coerce value \"a\" to Int), 1 (Could not coerce value \"b\" to Int), 2 (Could not coerce value \"c\" to Int)",
"locations": [
{
"line": 1,
"column": 13
}
],
"extensions": {
"value": [
"a",
"b",
"c"
],
"problems": [
{
"path": [
0
],
"explanation": "Could not coerce value \"a\" to Int"
},
{
"path": [
1
],
"explanation": "Could not coerce value \"b\" to Int"
},
{
"path": [
2
],
"explanation": "Could not coerce value \"c\" to Int"
}
]
}
}
]
}
今回は3つだったから良いですが、上記クエリーはidの配列を受け取るので下記のように大量のargumentsを指定することもできます。
下記のように100万個の不正なargumentsが指定されれば100万個のエラーを全て検証して、全エラー内容を返却するということです。
{
"ids": [
"a1",
"a2"
...(省略)
"a1000000"
]
}
ではどうするか?
そこで役に立つのが、validate_max_errors
です!
テンプレートのようにvalidate_max_errors(100)
と指定して、大量の不正なargumentsを指定します。
すると、下記のようにvalidate_max_errorsで指定して100個エラーになるまでは今まで通り検証されるのですが、100を超えると検証が中断されて、"Too many errors processing list variable, max validation error limit reached. Execution aborted"というエラーが返却されます。
{
"path": [
99
],
"explanation": "Could not coerce value \"a100\" to Int"
},
{
"path": [
null
],
"explanation": "Too many errors processing list variable, max validation error limit reached. Execution aborted"
}
argumentsの検証で重い処理をすることはほとんどないと思いますが、argumentsエラーはクライアントから簡単に起こすことができるのと、そもそもargumentsエラーの内容が全て必要になることはほぼないと思うので、validate_max_errorsはぜひ設定しておきましょう!!