Doctrine annotations VS PHP8 attributes
GraphQLite is heavily relying on the concept of annotations (also called attributes in PHP 8+).
Doctrine annotations
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 theuse
statements at the top of your file.
Some IDEs provide support for Doctrine annotations:
- PhpStorm via the PHP Annotations Plugin
- Eclipse via the Symfony 2 Plugin
- Netbeans has native support
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:
<?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),
]);
};