Object Type Definition¶
Object Type is the most frequently used primitive in a typical GraphQL application.
Conceptually Object Type is a collection of Fields. Each field, in turn, has its own type which allows building complex hierarchies.
Writing Object Types¶
In graphql-php object type is an instance of GraphQL\Type\Definition\ObjectType
(or one of its subclasses) which accepts a configuration array in its constructor:
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Examples\Blog\Data\DataSource;
use GraphQL\Examples\Blog\Data\Story;
$userType = new ObjectType([
'name' => 'User',
'description' => 'Our blog visitor',
'fields' => [
'firstName' => [
'type' => Type::string(),
'description' => 'User first name'
],
'email' => Type::string()
]
]);
$blogStory = new ObjectType([
'name' => 'Story',
'fields' => [
'body' => Type::string(),
'author' => [
'type' => $userType,
'description' => 'Story author',
'resolve' => fn (Story $blogStory): ?User => DataSource::findUser($blogStory->authorId),
],
'likes' => [
'type' => Type::listOf($userType),
'description' => 'List of users who liked the story',
'args' => [
'limit' => [
'type' => Type::int(),
'description' => 'Limit the number of recent likes returned',
'defaultValue' => 10
]
],
'resolve' => fn (Story $blogStory, array $args): array => DataSource::findLikes($blogStory->id, $args['limit']),
]
]
]);
This example uses inline style for Object Type definitions, but you can also use
inheritance or schema definition language.
Configuration options¶
Option | Type | Notes |
---|---|---|
name | string |
Required. Unique name of this object type within Schema |
fields | array or callable |
Required. An array describing object fields or callable returning such an array. See field configuration options section below for expected structure of each array entry. See also the section on Circular types for an explanation of when to use callable for this option. |
description | string |
Plain-text description of this type for clients (e.g. used by GraphiQL for auto-generated documentation) |
interfaces | array or callable |
List of interfaces implemented by this type or callable returning such a list. See Interface Types for details. See also the section on Circular types for an explanation of when to use callable for this option. |
isTypeOf | callable |
function ($value, $context, ResolveInfo $info): bool Expected to return true if $value qualifies for this type (see section about Abstract Type Resolution for explanation). |
resolveField | callable |
function ($value, array $args, $context, ResolveInfo $info): mixed Given the $value of this type, it is expected to return value for a field defined in $info->fieldName. A good place to define a type-specific strategy for field resolution. See section on Data Fetching for details. |
argsMapper | callable |
function (array $args, FieldDefinition, FieldNode): mixed Called once, when Executor resolves arguments for given field. Could be used to validate args and/or to map them to DTO/Object. |
visible | bool or callable |
Defaults to true . The given callable receives no arguments and is expected to return a bool , it is called once when the field may be accessed. The field is treated as if it were not defined at all when this is false . |
Field configuration options¶
Option | Type | Notes |
---|---|---|
name | string |
Required. Name of the field. When not set - inferred from fields array key (read about shorthand field definition below) |
type | Type |
Required. An instance of internal or custom type. Note: type must be represented by a single instance within one schema (see also lazy loading of types) |
args | array |
An array describing any number of possible field arguments, each element being an array. See field argument configuration options. |
resolve | callable |
function ($objectValue, array $args, $context, ResolveInfo $info): mixed Given the $objectValue of this type, it is expected to return actual value of the current field. See section on Data Fetching for details |
complexity | callable |
function (int $childrenComplexity, array $args): int Used to restrict query complexity. The feature is disabled by default, read about Security to use it. |
description | string |
Plain-text description of this field for clients (e.g. used by GraphiQL for auto-generated documentation) |
deprecationReason | string |
Text describing why this field is deprecated. When not empty - field will not be returned by introspection queries (unless forced) |
Field argument configuration options¶
Option | Type | Notes |
---|---|---|
name | string |
Required. Name of the argument. When not set - inferred from args array key |
type | Type |
Required. Instance of one of Input Types (scalar, enum, InputObjectType + any combination of those with nonNull and listOf modifiers) |
description | string |
Plain-text description of this argument for clients (e.g. used by GraphiQL for auto-generated documentation) |
defaultValue | scalar |
Default value for this argument. Use the internal value if specifying a default for an enum type |
Shorthand field definitions¶
Fields can be also defined in shorthand notation (with only name and type options):
'fields' => [
'id' => Type::id(),
'fieldName' => $fieldType
]
which is equivalent of:
'fields' => [
'id' => ['type' => Type::id()],
'fieldName' => ['type' => $fieldName]
]
which is in turn equivalent of the full form:
'fields' => [
['name' => 'id', 'type' => Type::id()],
['name' => 'fieldName', 'type' => $fieldName]
]
Same shorthand notation applies to field arguments as well.
Recurring and circular types¶
Almost all real-world applications contain recurring or circular types. Think user friends or nested comments for example.
graphql-php allows such types, but you have to use callable
in
option fields (and/or interfaces).
For example:
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Definition\ObjectType;
$userType = new ObjectType([
'name' => 'User',
'fields' => function () use (&$userType): array {
return [
'email' => [
'type' => Type::string()
],
'friends' => [
'type' => Type::listOf($userType)
]
];
},
]);
Same example for inheritance style of type definitions using a type registry (see lazy loading of types):
use GraphQL\Type\Definition\ListOfType;
use GraphQL\Type\Definition\ScalarType;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Definition\ObjectType;
class UserType extends ObjectType
{
public function __construct()
{
parent::__construct([
'fields' => [
'email' => fn (): ScalarType => MyTypes::string(),
'friends' => fn (): ListOfType => MyTypes::listOf(MyTypes::user())
],
]);
}
}
class MyTypes
{
private static UserType $user;
public static function user(): UserType
{
return self::$user ??= new UserType();
}
public static function string(): ScalarType
{
return Type::string();
}
public static function listOf($type): ListOfType
{
return Type::listOf($type);
}
}
Field Resolution¶
Field resolution is the primary mechanism in graphql-php for returning actual data for your fields. It is implemented using resolveField callable in type definition or resolve callable in field definition (which has precedence).
Read the section on Data Fetching for a complete description of this process.
Custom Metadata¶
All types in graphql-php accept configuration array. In some cases, you may be interested in passing your own metadata for type or field definition.
graphql-php preserves original configuration array in every type or field instance in public property $config. Use it to implement app-level mappings and definitions.