Inputs and Input Objects
Input types specify the structure of the values that inputs to resolvers should have. Scalars and Enums can be passed as input to resolvers. Wrapper types such as List and NonNull types of Scalars and Enums, also can be passed, however for more complex Objects with nested fields you will need to use GraphQLInputObjectType
. Similar GraphQLObjectType
, a GraphQLInputObjectType
can have fields.
// TODO: 1A customDeserialize with SerdeCtx deserializers
final inputModel = GraphQLInputObjectType(
'ModelInput',
description: '',
inputs: [
],
);
Field inputs (or Arguments) can be used in multiple places:
GraphQLObjectType.fields.inputs
: Inputs in field resolversGraphQLInputObjectType.fields
: Fields in Input ObjectsGraphQLDirective.inputs
: Inputs in directives
Not all types can be input types, in particular, object types and union types can't be input types nor part of a GraphQLInputObjectType
.
static bool isInputType(GraphQLType type) {
return type.when(
enum_: (type) => true,
scalar: (type) => true,
input: (type) => true,
object: (type) => false,
union: (type) => false,
list: (type) => isInputType(type.ofType),
nonNullable: (type) => isInputType(type.ofType),
);
}
Example
input ComplexInput {
value: String!
}
# The fields:
(
"""The amount"""
@deprecated
amount: Int = 2
names: [String!]
complex: ComplexInput!
)
()
class ComplexInput {
const ComplexInput({required this.value});
/// The value
final String value;
factory ComplexInput.fromJson(Map<String, Object?> json) =>
ComplexInput(
value: json['value']! as String,
);
}
final fields = [
GraphQLFieldInput(
'amount',
graphQLInt,
defaultValue: 2,
description: 'The amount',
// an empty String will use the default deprecation reason
deprecationReason: '',
),
GraphQLFieldInput(
'names',
listOf(graphQLString.nonNull()),
),
GraphQLFieldInput(
'complex',
complexInputGraphQLInputType.nonNull(),
),
];
// can be used in:
// - `GraphQLObjectType.fields.inputs`
// - `GraphQLInputObjectType.fields`
// - 'GraphQLDirective.inputs'
final object = GraphQLObjectType(
'ObjectName',
fields: [
stringGraphQLType.field(
'someField',
inputs: fields,
resolve: (_, Ctx ctx) {
final Map<String, Object?> args = ctx.args;
assert(args.containKey('complex'));
assert(args['names'] is List<String>?);
assert(args['amount'] is int?);
return '';
}
)
]
);
final objectInput = GraphQLInputObjectType(
'InputObjectName',
fields: fields,
// ...
);
final directive = GraphQLDirective(
name: 'DirectiveName',
inputs: fields,
// ...
);
InputObject.isOneOf
oneOf input object types allow you to specify that an object should contain only one of the provided fields. The fields should be nullable and should not have a default value. This is similar to union types. However, oneOf input types can be used as inputs and their variants (or fields) can be any input type such as a custom scalar, they are not constrained to object types.
input EmailPassword {
email: String!
password: String!
}
input LogInOption @oneOf {
email: EmailPassword
token: String
}
type Mutation {
login(option: LogInOption!): Boolean!
}
mutation loginMut {
login(option: { email: { email: "email@example.com" password: "pass" } })
}
InputObject.fromJson
For code generation, each class annotated as GraphQLInput
should have a factory constructor or static method name fromJson
in its class definition. This will be used as the method for deserializing instances of this class.