Type References#
Each Scalar
, Enum
, Object
, and InputObject
type has a unique name. NonNull
and List
are wrapper types
that modify named types. Most nodes in GraphQL have a type, such as fields and
arguments.
A type can be referenced by importing and passing the actual Python object around. However, this can get tedious, and can cause circular import issues when splitting up definitions across multiple files. Magql allows referring to types by name instead of the Python object.
import magql
magql.Field(magql.String)
magql.Field("String")
It’s possible to create circular references to types. Within an object, a
field’s type can be the object itself, or less directly through a chain of other
fields. For example, a User
with a friend
field that is another user. In
this case, you must refer to the type by name, this is called a forward
reference.
import magql
User = magql.Object("User", fields={
"username": "String",
"friend" "User"
})
Resolving References#
The schema must have a defined type object for every type name in the graph.
Calling Schema.to_graphql()
will traverse the graph and collect all named
type objects, then replace any string references with the corresponding object.
In the example below, the User
object is defined when defining the second
field, so the schema will know about it and apply it to the "User"
name in the
first field. Order does not matter, as long as the object is defined somewhere
in the schema.
import magql
schema = magql.Schema()
schema.query.fields["user"] = magql.Field("User")
schema.mutation.fields["create_user"] = magql.Field(magql.Object("User"))
You can also tell the schema about a type directly, so that every reference can
be a string, avoiding the nested definition above. You can pass the type when
creating the schema, or by calling Schema.add_type()
.
import magql
User = magql.Object("User")
schema = magql.Schema(types=[User])
import magql
schema = magql.Schema()
User = magql.Object("User")
schema.add_type(User)
If you try to call Schema.to_graphql()
while some names are still
undefined, you’ll get an error message.
Could not find definitions for the following type names: User. All types must be
defined somewhere in the graph, or passed when creating the Schema.
Wrapping Types#
Every type object has two properties, non_null
and
list
which return corresponding NonNull
and
List
. List
and NonNull
have these properties too, so you can create
arbitrarily nested structures. When using a string reference, you can use the
same syntax as GraphQL to apply wrappers.
In the following example, both fields will have the same type, a non-null list of non-null strings.
import magql
magql.Field(magql.String.non_null.list.non_null)
magql.Field("[String!]!")