Skip to main content
Version: Next

Doctrine annotations VS PHP8 attributes

GraphQLite is heavily relying on the concept of annotations (also called attributes in PHP 8+).

Doctrine annotations

Deprecated! Doctrine annotations are deprecated in favor of native PHP 8 attributes. Support will be dropped in a future release.

Historically, attributes were not available in PHP and PHP developers had to "trick" PHP to get annotation support. This was the purpose of the doctrine/annotation library.

Using Doctrine annotations, you write annotations in your docblocks:

use TheCodingMachine\GraphQLite\Annotations\Type;

/**
* @Type
*/
class MyType
{
}

Please note that:

  • The annotation is added in a docblock (a comment starting with "/**")
  • The Type part is actually a class. It must be declared in the use statements at the top of your file.
Heads up!

Some IDEs provide support for Doctrine annotations:

We strongly recommend using an IDE that has Doctrine annotations support.

PHP 8 attributes

Starting with PHP 8, PHP got native annotations support. They are actually called "attributes" in the PHP world.

The same code can be written this way:

use TheCodingMachine\GraphQLite\Annotations\Type;

#[Type]
class MyType
{
}

GraphQLite v4.1+ has support for PHP 8 attributes.

The Doctrine annotation class and the PHP 8 attribute class is the same (so you will be using the same use statement at the top of your file).

They support the same attributes too.

A few notable differences:

  • PHP 8 attributes do not support nested attributes (unlike Doctrine annotations). This means there is no equivalent to the annotations attribute of @MagicField and @SourceField.
  • PHP 8 attributes can be written at the parameter level. Any attribute targeting a "parameter" must be written at the parameter level.

Let's take an example with the #Autowire attribute:

#[Field]
public function getProduct(#[Autowire] ProductRepository $productRepository) : Product {
//...
}

Migrating from Doctrine annotations to PHP 8 attributes

The good news is that you can easily migrate from Doctrine annotations to PHP 8 attributes using the amazing, Rector library. To do so, you'll want to use the following rector configuration:

rector.php
<?php

use Rector\Core\Configuration\Option;
use Rector\Php80\Rector\Class_\AnnotationToAttributeRector;
use Rector\Php80\ValueObject\AnnotationToAttribute;
use Rector\Set\ValueObject\SetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use TheCodingMachine\GraphQLite\Annotations as GraphQLite;

return static function (ContainerConfigurator $containerConfigurator): void {
// Here we can define, what sets of rules will be applied
// tip: use "SetList" class to autocomplete sets
// $containerConfigurator->import(SetList::CODE_QUALITY);

// Set parameters
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [
__DIR__ . '/src',
__DIR__ . '/tests',
]);

$services = $containerConfigurator->services();

// @Validate and @Assertion are part of other libraries, include if necessary
$services->set(AnnotationToAttributeRector::class)
->configure([
new AnnotationToAttribute(GraphQLite\Query::class),
new AnnotationToAttribute(GraphQLite\Mutation::class),
new AnnotationToAttribute(GraphQLite\Type::class),
new AnnotationToAttribute(GraphQLite\ExtendType::class),
new AnnotationToAttribute(GraphQLite\Input::class),
new AnnotationToAttribute(GraphQLite\Field::class),
new AnnotationToAttribute(GraphQLite\SourceField::class),
new AnnotationToAttribute(GraphQLite\MagicField::class),
new AnnotationToAttribute(GraphQLite\Logged::class),
new AnnotationToAttribute(GraphQLite\Right::class),
new AnnotationToAttribute(GraphQLite\FailWith::class),
new AnnotationToAttribute(GraphQLite\HideIfUnauthorized::class),
new AnnotationToAttribute(GraphQLite\InjectUser::class),
new AnnotationToAttribute(GraphQLite\Security::class),
new AnnotationToAttribute(GraphQLite\Factory::class),
new AnnotationToAttribute(GraphQLite\UseInputType::class),
new AnnotationToAttribute(GraphQLite\Decorate::class),
new AnnotationToAttribute(GraphQLite\Autowire::class),
new AnnotationToAttribute(GraphQLite\HideParameter::class),
new AnnotationToAttribute(GraphQLite\EnumType::class),
]);
};