Skip to main content
Version: 4.3

Type mapping

As explained in the queries section, the job of GraphQLite is to create GraphQL types from PHP types.

Scalar mapping

Scalar PHP types can be type-hinted to the corresponding GraphQL types:

  • string
  • int
  • bool
  • float

For instance:

namespace App\Controller;

use TheCodingMachine\GraphQLite\Annotations\Query;

class MyController
{
#[Query]
public function hello(string $name): string
{
return 'Hello ' . $name;
}
}

Class mapping

When returning a PHP class in a query, you must annotate this class using @Type and @Field annotations:

namespace App\Entities;

use TheCodingMachine\GraphQLite\Annotations\Field;
use TheCodingMachine\GraphQLite\Annotations\Type;

#[Type]
class Product
{
// ...

#[Field]
public function getName(): string
{
return $this->name;
}

#[Field]
public function getPrice(): ?float
{
return $this->price;
}
}

Note: The GraphQL output type name generated by GraphQLite is equal to the class name of the PHP class. So if your PHP class is App\Entities\Product, then the GraphQL type will be named "Product".

In case you have several types with the same class name in different namespaces, you will face a naming collision. Hopefully, you can force the name of the GraphQL output type using the "name" attribute:

#[Type(name: "MyProduct")]
class Product { /* ... */ }

Array mapping

You can type-hint against arrays (or iterators) as long as you add a detailed @return statement in the PHPDoc.

/**
* @return User[] <=== we specify that the array is an array of User objects.
*/
#[Query]
public function users(int $limit, int $offset): array
{
// Some code that returns an array of "users".
}

ID mapping

GraphQL comes with a native ID type. PHP has no such type.

There are two ways with GraphQLite to handle such type.

Force the outputType

#[Field(outputType: "ID")]
public function getId(): string
{
// ...
}

Using the outputType attribute of the @Field annotation, you can force the output type to ID.

You can learn more about forcing output types in the custom types section.

ID class

use TheCodingMachine\GraphQLite\Types\ID;

#[Field]
public function getId(): ID
{
// ...
}

Note that you can also use the ID class as an input type:

use TheCodingMachine\GraphQLite\Types\ID;

#[Mutation]
public function save(ID $id, string $name): Product
{
// ...
}

Date mapping

Out of the box, GraphQL does not have a DateTime type, but we took the liberty to add one, with sensible defaults.

When used as an output type, DateTimeImmutable or DateTimeInterface PHP classes are automatically mapped to this DateTime GraphQL type.

#[Field]
public function getDate(): \DateTimeInterface
{
return $this->date;
}

The date field will be of type DateTime. In the returned JSON response to a query, the date is formatted as a string in the ISO8601 format (aka ATOM format).

PHP DateTime type is not supported.

Union types

You can create a GraphQL union type on the fly using the pipe | operator in the PHPDoc:

/**
* @return Company|Contact <== can return a company OR a contact.
*/
#[Query]
public function companyOrContact(int $id)
{
// Some code that returns a company or a contact.
}

Enum types

Available in GraphQLite 4.0+

PHP has no native support for enum types. Hopefully, there are a number of PHP libraries that emulate enums in PHP. The most commonly used library is myclabs/php-enum and GraphQLite comes with native support for it.

You will first need to install myclabs/php-enum:

$ composer require myclabs/php-enum

Now, any class extending the MyCLabs\Enum\Enum class will be mapped to a GraphQL enum:

use MyCLabs\Enum\Enum;

class StatusEnum extends Enum
{
private const ON = 'on';
private const OFF = 'off';
private const PENDING = 'pending';
}
/**
* @return User[]
*/
#[Query]
public function users(StatusEnum $status): array
{
if ($status == StatusEnum::ON()) {
// Note that the "magic" ON() method returns an instance of the StatusEnum class.
// Also, note that we are comparing this instance using "==" (using "===" would fail as we have 2 different instances here)
// ...
}
// ...
}
query users($status: StatusEnum!) {}
users(status: $status) {
id
}
}

By default, the name of the GraphQL enum type will be the name of the class. If you have a naming conflict (two classes that live in different namespaces with the same class name), you can solve it using the @EnumType annotation:

use TheCodingMachine\GraphQLite\Annotations\EnumType;

#[EnumType(name: "UserStatus")]
class StatusEnum extends Enum
{
// ...
}
GraphQLite must be able to find all the classes extending the "MyCLabs\Enum" class in your project. By default, GraphQLite will look for "Enum" classes in the namespaces declared for the types. For this reason, your enum classes MUST be in one of the namespaces declared for the types in your GraphQLite configuration file.
There are many enumeration library in PHP and you might be using another library. If you want to add support for your own library, this is not extremely difficult to do. You need to register a custom "RootTypeMapper" with GraphQLite. You can learn more about type mappers in the "internals" documentationand copy/paste and adapt the root type mapper used for myclabs/php-enum.

Deprecation of fields

You can mark a field as deprecated in your GraphQL Schema by just annotating it with the @deprecated PHPDoc annotation.

namespace App\Entities;

use TheCodingMachine\GraphQLite\Annotations\Field;
use TheCodingMachine\GraphQLite\Annotations\Type;

/**
* @Type()
*/
class Product
{
// ...

/**
* @Field()
*/
public function getName(): string
{
return $this->name;
}

/**
* @Field()
* @deprecated use field `name` instead
*/
public function getProductName(): string
{
return $this->name;
}
}

This will add the @deprecated directive to the field in the GraphQL Schema which sets the isDeprecated field to true and adds the reason to the deprecationReason field in an introspection query. Fields marked as deprecated can still be queried, but will be returned in an introspection query only if includeDeprecated is set to true.

query {
__type(name: "Product") {
fields(includeDeprecated: true) {
name
isDeprecated
deprecationReason
}
}
}

More scalar types

Available in GraphQLite 4.0+

GraphQL supports "custom" scalar types. GraphQLite supports adding more GraphQL scalar types.

If you need more types, you can check the GraphQLite Misc. Types library. It adds support for more scalar types out of the box in GraphQLite.

Or if you have some special needs, you can develop your own scalar types.