uxf / gql
3.56.3
2024-12-18 10:59 UTC
Requires
- php: ^8.3
- thecodingmachine/graphqlite: ^7.0
- uxf/core: 3.56.3
- dev-main
- 3.56.3
- 3.56.2
- 3.56.1
- 3.56.0
- 3.55.9
- 3.55.8
- 3.55.7
- 3.55.5
- 3.55.0
- 3.54.5
- 3.54.4
- 3.54.3
- 3.54.2
- 3.54.1
- 3.54.0
- 3.53.7
- 3.53.3
- 3.53.2
- 3.53.1
- 3.53.0
- 3.51.3
- 3.51.2
- 3.51.0
- 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-12-18 10:03:48 UTC
README
Install
$ composer req uxf/gql
Config
// 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
]);
};
Supports by default
- all PHP native types (native BackedEnum too)
UXF\Core\Type\Date
UXF\Core\Type\DateTime
UXF\Core\Type\Time
Ramsey\Uuid\UuidInterface
Usage
Query
#[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
#[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
#[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
#[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 argument
#[Entity]
- by default generateInt!
argument (you can specify property name byproperty
arg.)
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
#[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
#[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
{
...
}
}
Authentication + Authorization
Allowed in Query and Mutation.
#[Logged]
check logged user (only Q+M)#[Right(Role::USER_ROOT)]
check user role (only Q+M)#[InjectUser]
inject current user (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
{
...
}
}
ResponseCallbackModifier
Allow modify final response.
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;
}
}
Tools
bin/console uxf:gql-gen
generate .graphql file
List of all controllers
$services->set(Service::class)
->arg('$controllerNames', param('uxf_gql.controller_names'));
External packages and permissions
Autocomplete (uxf/cms) + DataGrid (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);
}