Skip to content

Commit 6eb4a43

Browse files
authored
graphql: support default variables (#920)
See: https://graphql.org/learn/queries/#default-variables Note: there is a difference between explicitly passed "null" value and just omitted variable. See graphql/graphql-spec#418 Closes #866
1 parent b25f05c commit 6eb4a43

File tree

3 files changed

+145
-3
lines changed

3 files changed

+145
-3
lines changed

cartridge/graphql/execute.lua

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,16 +240,26 @@ local function getFieldEntry(objectType, object, fields, context)
240240
argumentMap[argument.name.value] = argument
241241
end
242242

243+
local defaultValues = {}
244+
if context.operation.variableDefinitions ~= nil then
245+
for _, value in ipairs(context.operation.variableDefinitions) do
246+
if value.defaultValue ~= nil then
247+
local variableType = query_util.typeFromAST(value.type, context.schema)
248+
defaultValues[value.variable.name.value] = util.coerceValue(value.defaultValue, variableType)
249+
end
250+
end
251+
end
252+
243253
local arguments = util.map(fieldType.arguments or {}, function(argument, name)
244254
local supplied = argumentMap[name] and argumentMap[name].value
245255

246256
supplied = util.coerceValue(supplied, argument, context.variables,
247257
{strict_non_null = true})
248-
if supplied ~= nil then
258+
if type(supplied) ~= 'nil' then
249259
return supplied
250260
end
251261

252-
return argument.defaultValue
262+
return defaultValues[name]
253263
end)
254264

255265
--[[

cartridge/graphql/rules.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,8 @@ function rules.variableDefaultValuesHaveCorrectType(node, context)
410410
if definition.type.kind == 'nonNullType' and definition.defaultValue then
411411
error('Non-null variables can not have default values')
412412
elseif definition.defaultValue then
413-
util.coerceValue(definition.defaultValue, context.schema:getType(definition.type.name.value))
413+
local variableType = query_util.typeFromAST(definition.type, context.schema)
414+
util.coerceValue(definition.defaultValue, variableType)
414415
end
415416
end
416417
end

test/integration/graphql_test.lua

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,3 +779,134 @@ function g.test_middleware()
779779
}
780780
)
781781
end
782+
783+
g.test_default_values = function()
784+
local server = cluster.main_server
785+
786+
server.net_box:eval([[
787+
package.loaded['test'] = package.loaded['test'] or {}
788+
package.loaded['test']['test_default_value'] = function(_, args)
789+
if args.arg == nil then
790+
return 'nil'
791+
end
792+
return args.arg
793+
end
794+
795+
package.loaded['test']['test_default_list'] = function(_, args)
796+
if args.arg == nil then
797+
return 'nil'
798+
end
799+
return args.arg[1]
800+
end
801+
802+
package.loaded['test']['test_default_object'] = function(_, args)
803+
if args.arg == nil then
804+
return 'nil'
805+
end
806+
return args.arg.field
807+
end
808+
809+
local graphql = require('cartridge.graphql')
810+
local types = require('cartridge.graphql.types')
811+
812+
graphql.add_callback({
813+
name = 'test_default_value',
814+
args = {
815+
arg = types.string,
816+
},
817+
kind = types.string,
818+
callback = 'test.test_default_value',
819+
})
820+
821+
graphql.add_callback({
822+
name = 'test_default_list',
823+
args = {
824+
arg = types.list(types.string),
825+
},
826+
kind = types.string,
827+
callback = 'test.test_default_list',
828+
})
829+
830+
local input_object = types.inputObject({
831+
name = 'default_input_object',
832+
fields = {
833+
field = types.string,
834+
}
835+
})
836+
837+
graphql.add_callback({
838+
name = 'test_default_object',
839+
args = {
840+
arg = input_object,
841+
},
842+
kind = types.string,
843+
callback = 'test.test_default_object',
844+
})
845+
]])
846+
847+
t.assert_equals(
848+
server:graphql({
849+
query = [[
850+
query($arg: String = "default_value") {
851+
test_default_value(arg: $arg)
852+
}
853+
]],
854+
variables = {}}
855+
).data.test_default_value, 'default_value'
856+
)
857+
858+
t.assert_equals(
859+
server:graphql({
860+
query = [[
861+
query($arg: String = "default_value") {
862+
test_default_value(arg: $arg)
863+
}
864+
]],
865+
variables = {arg = box.NULL}}
866+
).data.test_default_value, 'nil'
867+
)
868+
869+
t.assert_equals(
870+
server:graphql({
871+
query = [[
872+
query($arg: [String] = ["default_value"]) {
873+
test_default_list(arg: $arg)
874+
}
875+
]],
876+
variables = {}}
877+
).data.test_default_list, 'default_value'
878+
)
879+
880+
t.assert_equals(
881+
server:graphql({
882+
query = [[
883+
query($arg: [String] = ["default_value"]) {
884+
test_default_list(arg: $arg)
885+
}
886+
]],
887+
variables = {arg = box.NULL}}
888+
).data.test_default_list, 'nil'
889+
)
890+
891+
t.assert_equals(
892+
server:graphql({
893+
query = [[
894+
query($arg: default_input_object = {field: "default_value"}) {
895+
test_default_object(arg: $arg)
896+
}
897+
]],
898+
variables = {}}
899+
).data.test_default_object, 'default_value'
900+
)
901+
902+
t.assert_equals(
903+
server:graphql({
904+
query = [[
905+
query($arg: default_input_object = {field: "default_value"}) {
906+
test_default_object(arg: $arg)
907+
}
908+
]],
909+
variables = {arg = box.NULL}}
910+
).data.test_default_object, 'nil'
911+
)
912+
end

0 commit comments

Comments
 (0)