uxf / gql
3.50.6
2024-09-27 07:48 UTC
Requires
- php: ^8.3
- thecodingmachine/graphqlite: ^7.0
- uxf/core: 3.50.6
- dev-main
- 3.50.6
- 3.50.5
- 3.50.4
- 3.50.3
- 3.50.2
- 3.50.1
- 3.50.0
- 3.49.2
- 3.49.1
- 3.49.0
- 3.48.0
- 3.47.2
- 3.47.0
- 3.46.11
- 3.44.6
- 3.44.5
- 3.44.4
- 3.44.3
- 3.44.2
- 3.44.0
- 3.43.2
- 3.43.0
- 3.42.0
- 3.41.2
- 3.41.1
- 3.41.0
- 3.40.4
- 3.40.3
- 3.40.2
- 3.40.1
- 3.40.0
- 3.39.5
- 3.39.4
- 3.39.3
- 3.39.2
- 3.39.1
- 3.39.0
- 3.38.0
- 3.37.1
- 3.37.0
- 3.36.3
- 3.36.2
- 3.36.0
- 3.35.5
- 3.35.4
- 3.35.2
- 3.34.3
- 3.34.0
- 3.32.4
- 3.32.3
- 3.32.1
- 3.30.1
- 3.29.1
- 3.29.0
- 3.27.6
- 3.27.3
- 3.27.2
- 3.27.1
- 3.26.2
- 3.26.0
- 3.24.6
- 3.24.2
- 3.24.1
- 3.24.0
- 3.23.3
- 3.23.1
- 3.23.0
- 3.22.2
- 3.22.1
- 3.22.0
- 3.21.6
- 3.21.4
- 3.21.3
- 3.21.1
- 3.21.0
- 3.20.0
- 3.19.4
- 3.19.2
- 3.18.1
- 3.18.0
- 3.17.4
- 3.17.3
- 3.17.2
- 3.17.1
- 3.17.0
- 3.15.6
- 3.15.5
- 3.15.0
- 3.13.3
- 3.13.2
- 3.13.1
- 3.13.0
- 3.11.3
- 3.11.2
- 3.11.0
- 3.10.2
- 3.10.1
- 3.10.0
- 3.9.2
- 3.8.2
- 3.8.1
- 3.8.0
- 3.7.3
- 3.7.1
- 3.7.0
- 3.6.0
- 3.5.0
- 3.4.0
- 3.3.0
- 3.2.4
- 3.2.3
- 3.2.2
- 3.2.1
- 3.2.0
- 3.1.4
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
This package is auto-updated.
Last update: 2024-09-27 05:52:43 UTC
README
安装
$ composer req uxf/gql
配置
// config/packages/uxf.php
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->extension('uxf_gql', [
'destination' => __DIR__ . '/../generated/schema.graphql', // or array
'sources' => [
__DIR__ . '/../src',
],
'injected' => [
// class => resolver
Coyote::class => CoyoteResolver::class,
],
'register_psr_17' => false, // default true
'allow_money' => true, // default false
'debug_flag' => DebugFlag::INCLUDE_DEBUG_MESSAGE, // default
]);
};
默认支持
- 所有PHP原生类型(包括原生BackedEnum)
UXF\Core\Type\Date
UXF\Core\Type\DateTime
UXF\Core\Type\Time
Ramsey\Uuid\UuidInterface
用法
查询
#[Query(name: 'name')]
use TheCodingMachine\GraphQLite\Annotations\Query;
class ArticlesQuery
{
public function __construct(private readonly ArticleProvider $articleProvider) {}
/**
* @return Article[]
*/
#[Query(name: 'articles')]
public function __invoke(int $limit, int $offset): array
{
return $this->articleProvider->list($limit, $offset);
}
}
突变
#[Mutation(name: 'name')]
use TheCodingMachine\GraphQLite\Annotations\Mutation;
class CreateArticleMutation
{
public function __construct(
private readonly ArticleCreator $articleCreator,
private readonly ArticleProvider $articleProvider,
) {}
#[Mutation(name: 'createArticle')]
public function __invoke(ArticleInput $input): Article
{
$article = $this->articleCreator->create($input);
return $this->articleProvider->get($article);
}
}
类型
#[Type]
+#[Field]
use App\Entity\Article as AppArticle;
use App\Entity\Tag as AppTag;
use TheCodingMachine\GraphQLite\Annotations\Field;
use TheCodingMachine\GraphQLite\Annotations\Type;
#[Type]
class Article
{
public function __construct(private readonly AppArticle $article) {}
#[Field]
public function id(): int
{
return $this->article->getId();
}
/**
* @return Tag[]
*/
#[Field]
public function tags(): array
{
return array_map(fn (AppTag $tag) => new Tag($tag), $this->article->getTags());
}
}
输入
#[Input]
+#[Field]
use TheCodingMachine\GraphQLite\Annotations\Input;
use TheCodingMachine\GraphQLite\Annotations\Field;
#[Input]
class ArticleInput
{
/**
* @param int[] $tags
*/
public function __construct(
#[Field]
public readonly string $title,
#[Field]
public readonly array $tags,
) {}
}
实体参数
#[Entity]
- 默认生成Int!
参数(您可以通过property
参数指定属性名)
use App\Entity\Donald as AppDonald;
use App\GQL\Type\Donald;
use TheCodingMachine\GraphQLite\Annotations\Query;
use UXF\GQL\Attribute\Entity;
class DonaldQuery
{
/**
* @param Donald[] $donalds
* @param Donald[]|null $donaldsNullable
* @param Donald[]|null $donaldsNullableOptional
* @param Donald[] $donaldsOptional
*/
#[Query(name: 'donald')]
public function __invoke(
#[Entity] AppDonald $donald,
#[Entity(property: 'uuid')] AppDonald $donald2,
#[Entity(AppDonald::class)] array $donalds,
#[Entity] ?AppDonald $donaldNullable,
#[Entity(AppDonald::class)] ?array $donaldsNullable,
#[Entity] ?AppDonald $donaldNullableOptional = null,
#[Entity(AppDonald::class)] ?array $donaldsNullableOptional = null,
#[Entity(AppDonald::class)] array $donaldsOptional = [],
): Donald {
return new Donald($donald);
}
}
type Query {
donald(
donald: Int!,
donald2: String!,
donalds: [Int!]!,
donaldNullable: Int,
donaldsNullable: [Int!],
donaldNullableOptional: Int = null,
donaldsNullableOptional: [Int!] = null,
donaldsOptional: [Int!]! = []
): Donald!
}
自动装配
#[Autowire]
use App\Entity\Article as AppArticle;
use App\Entity\Tag as AppTag;
use TheCodingMachine\GraphQLite\Annotations\Autowire;
use TheCodingMachine\GraphQLite\Annotations\Field;
use TheCodingMachine\GraphQLite\Annotations\Type;
#[Type]
class Article
{
...
/**
* @return Tag[]
*/
#[Field]
public function tags(#[Autowire] SomeService $service): array
{
return $someService->get();
}
}
注入
#[Inject]
use App\GQL\Type\Article;
use TheCodingMachine\GraphQLite\Annotations\Query;
use UXF\GQL\Attribute\Inject;
class ArticlesQuery
{
#[Query(name: 'article')]
public function __invoke(#[Inject] Coyote $coyote): Article
{
...
}
}
// config/packages/uxf.php
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->extension('uxf_gql', [
'injected' => [
// class => resolver
Coyote::class => CoyoteResolver::class,
// btw Symfony Request is autoregistered
],
]);
$containerConfigurator->services()
->set(CoyoteResolver::class);
};
class CoyoteResolver
{
public function __invoke(ReflectionNamedType $type, Request $request): Coyote
{
...
}
}
身份验证 + 授权
在查询和突变中允许。
#[Logged]
检查已登录用户(仅Q+M)#[Right(Role::USER_ROOT)]
检查用户角色(仅Q+M)#[InjectUser]
注入当前用户(Q+M+T)
use TheCodingMachine\GraphQLite\Annotations\Logged;
use TheCodingMachine\GraphQLite\Annotations\Mutation;
use TheCodingMachine\GraphQLite\Annotations\Right;
class CreateArticleMutation
{
#[Logged]
#[Right(Role::USER_ROOT)]
#[Mutation(name: 'createArticle')]
public function __invoke(#[InjectUser] User $user, ArticleInput $input): Article
{
...
}
}
响应回调修改器
允许修改最终响应。
class LoginMutation
{
public function __construct(private readonly ResponseCallbackModifier $responseModifier)
{
}
#[Mutation(name: 'login')]
public function __invoke(string $username, string $password): bool
{
$this->responseModifier->add(
fn (Response $response) => $response->headers->set('Auth-Token', '1')
);
return true;
}
}
工具
bin/console uxf:gql-gen
生成 .graphql 文件
外部包和权限
自动完成(uxf/cms)+ 数据网格(uxf/datagrid)
use UXF\Core\Contract\Permission\PermissionChecker;
final readonly class AppPermissionChecker implements PermissionChecker
{
public function __construct(private Security $security)
{
}
public function isAllowed(string $resourceType, string $resourceName): bool
{
// $resourceType - grid | autocomplete
// $resourceName - gridName | autocompleteName
return $this->security->isGranted('ROLE_ROOT');
}
}
// services.php
return static function (ContainerConfigurator $container): void {
$container->services()->set(PermissionChecker::class, AppPermissionChecker::class);
}