# Interface Type Definition
An Interface is an abstract type that includes a certain set of fields that a 
type must include to implement the interface.

In **graphql-php** interface type is an instance of `GraphQL\Type\Definition\InterfaceType` 
(or one of it subclasses) which accepts configuration array in constructor:

```php
use GraphQL\Type\Definition\InterfaceType;
use GraphQL\Type\Definition\Type;

$character = new InterfaceType([
    'name' => 'Character',
    'description' => 'A character in the Star Wars Trilogy',
    'fields' => [
        'id' => [
            'type' => Type::nonNull(Type::string()),
            'description' => 'The id of the character.',
        ],
        'name' => [
            'type' => Type::string(),
            'description' => 'The name of the character.'
        ]
    ],
    'resolveType' => function ($value) {
        if ($value->type === 'human') {
            return MyTypes::human();            
        } else {
            return MyTypes::droid();
        }
    }
]);
```
This example uses **inline** style for Interface definition, but you can also use  
[inheritance](/type-system/#type-definition-styles).

# Configuration options
Constructor of InterfaceType accepts an array. Below is a full list of allowed options:

Option | Type | Notes
------ | ---- | -----
name | `string` | **Required.** Unique name of this interface type within Schema
fields | `array` | **Required.** List of fields required to be defined by interface implementors. Same as [Fields for Object Type](#)
description | `string` | Plain-text description of this type for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
resolveType | `callback` returning instance of `ObjectType` | **function($value, $context, GraphQL\Type\Definition\ResolveInfo $info)** Any `callable` that receives `$value` from resolver of the parent field and returns concrete interface implementor for that `$value`.

# Implementing interface
To implement the Interface simply add it to **interfaces** array of Object Type definition:
```php
$humanType = new ObjectType([
    'name' => 'Human',
    'fields' => [
        'id' => [
            'type' => Type::nonNull(Type::string()),
            'description' => 'The id of the character.',
        ],
        'name' => [
            'type' => Type::string(),
            'description' => 'The name of the character.'
        ]
    ],
    'interfaces' => [
        $character
    ]
]);
```
Note that Object Type must include all fields of interface with exact same types 
(including **nonNull** specification) and arguments.

The only exception is when object's field type is more specific than the type of this field defined in interface 
(see [Covariant return types for interface fields](#covariant-return-types-for-interface-fields) below)

# Covariant return types for interface fields
Object types implementing interface may change field type to more specific.
Example:

```
interface A {
  field1: A
}

type B implements A {
  field1: B
}
```

# Sharing Interface fields
Since every Object Type implementing an Interface must have the same set of fields - it often makes 
sense to re-use field definitions of Interface in Object Types:

```php
$humanType = new ObjectType([
    'name' => 'Human',
    'interfaces' => [
        $character
    ],
    'fields' => [
        'height' => Type::float(),
        $character->getField('id'),
        $character->getField('name')
    ] 
]);
```

In this case field definitions are created only once (as a part of Interface Type) and then 
re-used by all interface implementors. It can save several microseconds and kilobytes + ensures that 
field definitions of Interface and implementors are always in sync.

Yet it creates a problem with resolution of such fields. There are two ways how shared fields could 
be resolved:

1. If field resolution algorithm is the same for all Interface implementors - you can simply add 
**resolve** option to field definition in Interface itself.

2. If field resolution varies from implementor to implementor - you can specify **resolveField** 
option in [Object Type config](/type-system/object-types/#configuration-options) and handle field 
resolutions there 
(Note: **resolve** option in field definition has precedence over **resolveField** option in object type definition)

# Interface role in data fetching
The only responsibility of interface in Data Fetching process is to return concrete Object Type 
for given `$value` in **resolveType**. Then resolution of fields is delegated to resolvers of this 
concrete Object Type.

If **resolveType** option is omitted, **graphql-php** will loop through all interface implementors and 
use their **isTypeOf** callback to pick the first suitable one. This is obviously less efficient 
than single **resolveType** call. So it is recommended to define **resolveType** whenever possible.
