api-skeletons / doctrine-graphql
8.1.3
2023-10-15 10:14 UTC
Requires
- php: ^8.0
- api-skeletons/doctrine-querybuilder-filter: ^2.0
- doctrine/doctrine-laminas-hydrator: ^3.2
- doctrine/orm: ^2.11
- league/event: ^3.0
- psr/container: ^1.1||^2.0
- webonyx/graphql-php: ^v15.0
Requires (Dev)
- doctrine/coding-standard: ^11.0 || ^12.0
- doctrine/dbal: ^3.1.1
- phpunit/phpunit: ^9.5
- ramsey/uuid: ^4.7
- symfony/cache: ^5.3||^6.2
- vimeo/psalm: ^5.4
- dev-main
- 8.1.3
- 8.1.2
- 8.1.1
- 8.1.0
- 8.0.0
- 7.2.2
- 7.2.1
- 7.2.0
- 7.1.5
- 7.1.4
- 7.1.3
- 7.1.2
- 7.1.1
- 7.1.0
- 7.0.5
- 7.0.4
- 7.0.3
- 7.0.2
- 7.0.1
- 7.0.0
- 6.2.5
- 6.2.4
- 6.2.3
- 6.2.2
- 6.2.1
- 6.2.0
- 6.1.10
- 6.1.9
- 6.1.8
- 6.1.7
- 6.1.6
- 6.1.5
- 6.1.4
- 6.1.3
- 6.1.2
- 6.1.1
- 6.1.0
- 6.0.7
- 6.0.6
- 6.0.5
- 6.0.4
- 6.0.3
- 6.0.2
- 6.0.1
- 6.0.0
- 5.1.1
- 5.1.0
- 5.0.5
- 5.0.4
- 5.0.3
- 5.0.2
- 5.0.1
- 5.0.0
- 4.0.1
- 4.0.0
- 3.0.1
- 3.0.0
- dev-dependabot/github_actions/dot-github/workflows/actions/download-artifact-4.1.7
This package is auto-updated.
Last update: 2024-09-03 21:31:24 UTC
README
该项目已被弃用,转而使用API-Skeletons/doctrine-orm-graphql
如果您是 8.x 分支的用户,请参阅升级指南
所有原始文档如下。
此库为 Doctrine ORM 提供了一个框架无关的 GraphQL 驱动程序,用于与webonyx/graphql-php一起使用。配置从零到详尽都有。支持多个驱动程序的多重配置。
详细的文档可在这里找到。
有关示例应用程序,请访问https://graphql.lcdb.org/
库亮点
- 使用PHP 8 属性
- 多个独立配置
- 支持所有默认的Doctrine 类型和自定义类型
- 支持GraphQL 完整连接模型
- 支持子集合的筛选
- 事件用于修改查询和实体类型
- 使用Doctrine Laminas Hydrator进行提取
- 符合Doctrine 编码规范
安装
运行以下命令使用Composer安装此库
composer require api-skeletons/doctrine-graphql
实体关系图
此实体关系图,由Skipper创建,用于下面的查询示例和测试此库。
快速入门
将属性添加到您的 Doctrine 实体中
use ApiSkeletons\Doctrine\GraphQL\Attribute as GraphQL; #[GraphQL\Entity] class Artist { #[GraphQL\Field] public $id; #[GraphQL\Field] public $name; #[GraphQL\Association] public $performances; } #[GraphQL\Entity] class Performance { #[GraphQL\Field] public $id; #[GraphQL\Field] public $venue; /** * Not all fields need attributes. * Only add attribues to fields you want available in GraphQL */ public $city; }
创建驱动程序和 GraphQL 模式
use ApiSkeletons\Doctrine\GraphQL\Driver; use Doctrine\ORM\EntityManager; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; use GraphQL\Type\Schema; $driver = new Driver($entityManager); $schema = new Schema([ 'query' => new ObjectType([ 'name' => 'query', 'fields' => [ 'artists' => [ 'type' => $driver->connection($driver->type(Artist::class)), 'args' => [ 'filter' => $driver->filter(Artist::class), 'pagination' => $driver->pagination(), ], 'resolve' => $driver->resolve(Artist::class), ], ], ]), 'mutation' => new ObjectType([ 'name' => 'mutation', 'fields' => [ 'artistUpdateName' => [ 'type' => $driver->type(Artist::class), 'args' => [ 'id' => Type::nonNull(Type::id()), 'input' => Type::nonNull($driver->input(Artist::class, ['name'])), ], 'resolve' => function ($root, $args) use ($driver): Artist { $artist = $driver->get(EntityManager::class) ->getRepository(Artist::class) ->find($args['id']); $artist->setName($args['input']['name']); $driver->get(EntityManager::class)->flush(); return $artist; }, ], ], ]), ]);
运行 GraphQL 查询
use GraphQL\GraphQL; $query = '{ artists { edges { node { id name performances { edges { node { venue } } } } } } }'; $result = GraphQL::executeQuery( schema: $schema, source: $query, variableValues: null, operationName: null ); $output = $result->toArray();
运行 GraphQL 变更
use GraphQL\GraphQL; $query = 'mutation ArtistUpdateName($id: Int!, $name: String!) { artistUpdateName(id: $id, input: { name: $name }) { id name } }'; $result = GraphQL::executeQuery( schema: $schema, source: $query, variableValues: ['id' => 1, 'name' => 'newName'], operationName: 'ArtistUpdateName' ); $output = $result->toArray();
筛选
对于每个属性字段和每个属性关联,您的 GraphQL 查询中都有筛选器。
示例
{ artists ( filter: { name: { contains: "dead" } } ) { edges { node { id name performances ( filter: { venue: { eq: "The Fillmore" } } ) { edges { node { venue } } } } } } }
每个字段都有自己的筛选器集合。大多数字段都有以下筛选器
- eq - 等于。
- neq - 不等于。
- lt - 小于。
- lte - 小于或等于。
- gt - 大于。
- gte - 大于或等于。
- isnull - 为空。如果值为 true,则字段必须为空。如果值为 false,则字段不能为空。
- between - 介于。等同于在同一个字段上使用 gte 和 lte。提供值作为
low, high
。 - in - 存在于以逗号分隔的值列表中。
- notin - 不存在于以逗号分隔的值列表中。
- startwith - 一个带有值右侧通配符的 like 查询。
- endswith - 在值左侧带有通配符的类似查询。
- contains - 一个类似查询。
事件
过滤查询构建器
您可以通过订阅事件来修改用于解决任何连接的查询构建器。每个连接可能具有一个独特的事件名称。Entity::class . '.filterQueryBuilder'
被推荐使用。将其作为$driver->resolve()
的第二个参数传递。
use ApiSkeletons\Doctrine\GraphQL\Event\FilterQueryBuilder; use App\ORM\Entity\Artist; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Schema; use League\Event\EventDispatcher; $schema = new Schema([ 'query' => new ObjectType([ 'name' => 'query', 'fields' => [ 'artists' => [ 'type' => $driver->connection($driver->type(Artist::class)), 'args' => [ 'filter' => $driver->filter(Artist::class), 'pagination' => $driver->pagination(), ], 'resolve' => $driver->resolve(Artist::class, Artist::class . '.filterQueryBuilder'), ], ], ]), ]); $driver->get(EventDispatcher::class)->subscribeTo(Artist::class . '.filterQueryBuilder', function(FilterQueryBuilder $event) { $event->getQueryBuilder() ->innerJoin('entity.user', 'user') ->andWhere($event->getQueryBuilder()->expr()->eq('user.id', ':userId')) ->setParameter('userId', currentUser()->getId()) ; } );
过滤关联条件
您可以修改用于过滤关联的准则对象。例如,如果您使用软删除,那么您可能希望从一个关联中过滤掉已删除的行。
use ApiSkeletons\Doctrine\GraphQL\Attribute as GraphQL; use ApiSkeletons\Doctrine\GraphQL\Event\FilterCriteria; use App\ORM\Entity\Artist; use League\Event\EventDispatcher; #[GraphQL\Entity] class Artist { #[GraphQL\Field] public $id; #[GraphQL\Field] public $name; #[GraphQL\Association(filterCriteriaEventName: self::class . '.performances.filterCriteria')] public $performances; } // Add a listener to your driver $driver->get(EventDispatcher::class)->subscribeTo( Artist::class . '.performances.filterCriteria', function (FilterCriteria $event): void { $event->getCriteria()->andWhere( $event->getCriteria()->expr()->eq('isDeleted', false) ); }, );
实体对象类型定义
您可以在创建实体类型之前修改用于定义该类型的数组。这可以用于生成数据等。您必须在定义您的GraphQL模式之前附加到事件。有关详细信息,请参阅详细文档。
use ApiSkeletons\Doctrine\GraphQL\Driver; use ApiSkeletons\Doctrine\GraphQL\Event\EntityDefinition; use App\ORM\Entity\Artist; use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\Type; use League\Event\EventDispatcher; $driver = new Driver($entityManager); $driver->get(EventDispatcher::class)->subscribeTo( Artist::class . '.definition', static function (EntityDefinition $event): void { $definition = $event->getDefinition(); // In order to modify the fields you must resovle the closure $fields = $definition['fields'](); // Add a custom field to show the name without a prefix of 'The' $fields['nameUnprefix'] = [ 'type' => Type::string(), 'description' => 'A computed dynamically added field', 'resolve' => static function ($objectValue, array $args, $context, ResolveInfo $info): mixed { return trim(str_replace('The', '', $objectValue->getName())); }, ]; $definition['fields'] = $fields; } );
进一步阅读
详细的文档可在这里找到。