Skip to main content

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.

GraphQL Specification

// 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 resolvers

  • GraphQLInputObjectType.fields: Fields in Input Objects

  • GraphQLDirective.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

Discussion

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.