Skip to main content

Generators

The GraphQl schema is mainly generated by GraphQl Generators. These are responsible for defining the schema and registering those objects in the Registry (Swift\GraphQl\Schema\Registry).

Those are classes implementing the Swift\GraphQl\Schema\Generator\GeneratorInterface interface. Those generators will be called by the GraphQl Schema Compiler. The Schema Compiler will call the run() method of each generator. And pass the Registry as an argument. It expects the generator to add the objects it wants to the Registry and return it.

It is recommended the use the Swift\GraphQl\Schema\Builder\Builder to create all objects. This will make it easier to add new objects to the Registry. For more information on how to use the Builder, see the Builder section.

The example below shows the declaration of the Access Tokens endpoints in the GraphQl schema.

<?php declare( strict_types=1 );
namespace Swift\Security\User\GraphQl\Schema\Generator;
use GraphQL\Type\Definition\Type;
use Swift\DependencyInjection\Attributes\Autowire;
use Swift\GraphQl\Schema\Builder\Builder;
use Swift\GraphQl\Schema\Builder\ObjectBuilder;
use Swift\GraphQl\Schema\Registry;
use Swift\GraphQl\Type\TypeFactory;
#[Autowire]
class AccessTokenGenerator implements \Swift\GraphQl\Schema\Generator\GeneratorInterface {
public function __construct(
protected \Swift\Security\User\GraphQl\Executor\ClientResolver $clientResolver,
) {
}
public function run( \Swift\GraphQl\Schema\Registry $registry ): \Swift\GraphQl\Schema\Registry {
$registry->extendType( 'Mutation', function ( ObjectBuilder $objectBuilder ) use ( $registry ) {
$accessTokenResponse = $this->generateAccessTokenResult( $registry );
$refreshTokenResponse = $this->generateRefreshTokenResult( $registry );
$objectBuilder->addField( 'AuthAccessTokenGet', [
'type' => static fn() => Registry::$typeMap[ $accessTokenResponse->getName() ],
'description' => 'Get an access token as client',
'args' => [
'grantType' => [
'type' => Type::string(),
],
'clientId' => [
'type' => Type::string(),
],
'clientSecret' => [
'type' => Type::string(),
],
],
'resolve' => function ( $objectValue, $args, $context, $info ) {
return $this->clientResolver->resolveAuthTokenGet( $objectValue, $args, $context, $info );
},
] );
$objectBuilder->addField( 'AuthRefreshToken', [
'type' => static fn() => Registry::$typeMap[ $refreshTokenResponse->getName() ],
'description' => 'Refresh an access token as client',
'args' => [
'grantType' => [
'type' => Type::string(),
],
'refreshToken' => [
'type' => Type::string(),
],
],
'resolve' => function ( $objectValue, $args, $context, $info ) {
return $this->clientResolver->resolveRefreshTokenGet( $objectValue, $args, $context, $info );
},
] );
} );
return $registry;
}
protected function generateAccessTokenResult( Registry $registry ): ObjectBuilder {
$object = Builder::objectType( 'AccessToken' )
->setDescription( 'Result of the forgot access token mutation' )
->addField( 'accessToken', Builder::fieldType( 'accessToken', Builder::nonNull( Type::string() ) )->buildType() )
->addField( 'expires', Builder::fieldType( 'expires', Builder::nonNull( TypeFactory::dateTime() ) )->buildType() )
->addField( 'refreshToken', Builder::fieldType( 'refreshToken', Builder::nonNull( Type::string() ) )->buildType() )
->addField( 'tokenType', Builder::fieldType( 'tokenType', Builder::nonNull( Type::string() ) )->buildType() );
$registry->objectType( $object );
return $object;
}
protected function generateRefreshTokenResult( Registry $registry ): ObjectBuilder {
$object = Builder::objectType( 'RefreshToken' )
->setDescription( 'Result of the forgot refresh token mutation' )
->addField( 'accessToken', Builder::fieldType( 'accessToken', Builder::nonNull( Type::string() ) )->buildType() )
->addField( 'expires', Builder::fieldType( 'expires', Builder::nonNull( TypeFactory::dateTime() ) )->buildType() )
->addField( 'tokenType', Builder::fieldType( 'tokenType', Builder::nonNull( Type::string() ) )->buildType() );
$registry->objectType( $object );
return $object;
}
}