diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml
index fca6c425e2507..d6168cdc37600 100644
--- a/app/code/Magento/GraphQl/etc/di.xml
+++ b/app/code/Magento/GraphQl/etc/di.xml
@@ -29,6 +29,7 @@
- Magento\Framework\GraphQl\Config\Element\InterfaceFactory
+ - Magento\Framework\GraphQl\Config\Element\UnionFactory
- Magento\Framework\GraphQl\Config\Element\TypeFactory
- Magento\Framework\GraphQl\Config\Element\InputFactory
- Magento\Framework\GraphQl\Config\Element\EnumFactory
@@ -64,6 +65,7 @@
- Magento\Framework\GraphQl\Schema\Type\Output\OutputTypeObject
- Magento\Framework\GraphQl\Schema\Type\Input\InputObjectType
- Magento\Framework\GraphQl\Schema\Type\Output\OutputInterfaceObject
+ - Magento\Framework\GraphQl\Schema\Type\Output\OutputUnionObject
- Magento\Framework\GraphQl\Schema\Type\Enum\Enum
@@ -78,6 +80,7 @@
- Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper\Formatter\Fields
- Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper\Formatter\Interfaces
+ - Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper\Formatter\Unions
- Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper\Formatter\ResolveType
@@ -85,6 +88,7 @@
+ - Magento\Framework\GraphQlSchemaStitching\GraphQlReader\Reader\UnionType
- Magento\Framework\GraphQlSchemaStitching\GraphQlReader\Reader\EnumType
- Magento\Framework\GraphQlSchemaStitching\GraphQlReader\Reader\ObjectType
- Magento\Framework\GraphQlSchemaStitching\GraphQlReader\Reader\InputObjectType
diff --git a/app/code/Magento/GraphQl/etc/schema.graphqls b/app/code/Magento/GraphQl/etc/schema.graphqls
index 2595ad09c072a..7366567c2b95d 100644
--- a/app/code/Magento/GraphQl/etc/schema.graphqls
+++ b/app/code/Magento/GraphQl/etc/schema.graphqls
@@ -30,14 +30,14 @@ directive @resolver(class: String="") on QUERY
| OBJECT
| FIELD_DEFINITION
| ARGUMENT_DEFINITION
- | INTERFACE
- | UNION
| ENUM
| ENUM_VALUE
| INPUT_OBJECT
| INPUT_FIELD_DEFINITION
-directive @typeResolver(class: String="") on INTERFACE | OBJECT
+directive @typeResolver(class: String="") on UNION
+ | INTERFACE
+ | OBJECT
directive @cache(cacheIdentity: String="" cacheable: Boolean=true) on QUERY
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php
index 1731a974aaed3..71ff93875f2c1 100644
--- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php
+++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php
@@ -11,6 +11,9 @@
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
+/**
+ * Resolver for Item
+ */
class Item implements ResolverInterface
{
/**
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/TestUnion.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/TestUnion.php
new file mode 100644
index 0000000000000..592b0caaa88a3
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/TestUnion.php
@@ -0,0 +1,34 @@
+ 'custom_name1_value',
+ 'custom_name2' => 'custom_name2_value',
+ ];
+ }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/UnionTypeResolver.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/UnionTypeResolver.php
new file mode 100644
index 0000000000000..40cbdadb8a948
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/UnionTypeResolver.php
@@ -0,0 +1,27 @@
+assertArrayHasKey('testItem', $response);
}
+
+ public function testQueryTestUnionResults()
+ {
+ $query = <<graphQlQuery($query);
+
+ $this->assertArrayHasKey('testUnion', $response);
+ $testUnion = $response['testUnion'];
+ $this->assertArrayHasKey('custom_name1', $testUnion);
+ $this->assertEquals('custom_name1_value', $testUnion['custom_name1']);
+ $this->assertArrayNotHasKey('custom_name2', $testUnion);
+ }
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/Type.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/Type.php
index 20d017cc71062..073fb2e795e87 100644
--- a/lib/internal/Magento/Framework/GraphQl/Config/Element/Type.php
+++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/Type.php
@@ -73,7 +73,15 @@ public function getFields() : array
/**
* Get interfaces the type implements, if any. Return an empty array if none are configured.
*
- * @return string[]
+ * Example return array(
+ * array(
+ * 'interface' => 'SomeDefinedTypeInterface',
+ * 'copyFields' => true
+ * ),
+ * ...
+ * ),
+ *
+ * @return array
*/
public function getInterfaces() : array
{
diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/UnionFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/UnionFactory.php
new file mode 100644
index 0000000000000..02d0a60064db6
--- /dev/null
+++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/UnionFactory.php
@@ -0,0 +1,69 @@
+objectManager = $objectManager;
+ }
+
+ /**
+ * Instantiate an object representing 'union' GraphQL config element.
+ *
+ * @param array $data
+ * @return ConfigElementInterface
+ */
+ public function createFromConfigData(array $data): ConfigElementInterface
+ {
+ return $this->create($data, $data['types'] ?? []);
+ }
+
+ /**
+ * Create union object based off array of configured GraphQL.
+ *
+ * Union data must contain name, type resolver, and possible concrete types definitions
+ * The type resolver should point to an implementation of the TypeResolverInterface
+ * that decides what concrete GraphQL type to output. Description is the only optional field.
+ *
+ * @param array $unionData
+ * @param array $types
+ * @return UnionType
+ */
+ public function create(
+ array $unionData,
+ array $types
+ ) : UnionType {
+ return $this->objectManager->create(
+ UnionType::class,
+ [
+ 'name' => $unionData['name'],
+ 'typeResolver' => $unionData['typeResolver'],
+ 'types' => $types,
+ 'description' => isset($unionData['description']) ? $unionData['description'] : ''
+ ]
+ );
+ }
+}
diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/UnionInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/UnionInterface.php
new file mode 100644
index 0000000000000..2d557e6dc5b84
--- /dev/null
+++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/UnionInterface.php
@@ -0,0 +1,23 @@
+name = $name;
+ $this->types = $types;
+ $this->typeResolver = $typeResolver;
+ $this->description = $description;
+ }
+
+ /**
+ * Get the type name.
+ *
+ * @return string
+ */
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ /**
+ * Get a list of fields that make up the possible return or input values of a type.
+ *
+ * @return string[]
+ */
+ public function getTypes(): array
+ {
+ return $this->types;
+ }
+
+ /**
+ * Return the name of the resolver class that determines the concrete type to display in the result.
+ *
+ * @return string
+ */
+ public function getTypeResolver(): string
+ {
+ return $this->typeResolver;
+ }
+
+ /**
+ * Get a human-readable description of the type.
+ *
+ * @return string
+ */
+ public function getDescription(): string
+ {
+ return $this->description;
+ }
+}
diff --git a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/SearchCriteria/ArgumentApplier/Filter.php b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/SearchCriteria/ArgumentApplier/Filter.php
index 0e5feeba3bade..5ec80b1d4692c 100644
--- a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/SearchCriteria/ArgumentApplier/Filter.php
+++ b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/SearchCriteria/ArgumentApplier/Filter.php
@@ -51,7 +51,7 @@ public function __construct(
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function applyArgument(
SearchCriteriaInterface $searchCriteria,
diff --git a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/SearchCriteria/ArgumentApplier/Sort.php b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/SearchCriteria/ArgumentApplier/Sort.php
index 6ecb1896d685a..d312837e41686 100644
--- a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/SearchCriteria/ArgumentApplier/Sort.php
+++ b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/SearchCriteria/ArgumentApplier/Sort.php
@@ -33,7 +33,7 @@ public function __construct(SortOrderBuilder $sortOrderBuilder = null)
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function applyArgument(
SearchCriteriaInterface $searchCriteria,
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Fields.php
index ad9fb675a6d70..3456f3c039a64 100644
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Fields.php
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Fields.php
@@ -10,6 +10,7 @@
use Magento\Framework\GraphQl\Config\Data\WrappedTypeProcessor;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Config\Element\TypeInterface;
+use Magento\Framework\GraphQl\Config\ConfigElementInterface;
use Magento\Framework\GraphQl\Schema\Type\Input\InputMapper;
use Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper\FormatterInterface;
use Magento\Framework\GraphQl\Schema\Type\Output\OutputMapper;
@@ -89,17 +90,20 @@ public function __construct(
/**
* @inheritdoc
*/
- public function format(TypeInterface $configElement, OutputTypeInterface $outputType): array
+ public function format(ConfigElementInterface $configElement, OutputTypeInterface $outputType): array
{
- $typeConfig = [
- 'fields' => function () use ($configElement, $outputType) {
- $fieldsConfig = [];
- foreach ($configElement->getFields() as $field) {
- $fieldsConfig[$field->getName()] = $this->getFieldConfig($configElement, $outputType, $field);
+ $typeConfig = [];
+ if ($configElement instanceof TypeInterface) {
+ $typeConfig = [
+ 'fields' => function () use ($configElement, $outputType) {
+ $fieldsConfig = [];
+ foreach ($configElement->getFields() as $field) {
+ $fieldsConfig[$field->getName()] = $this->getFieldConfig($configElement, $outputType, $field);
+ }
+ return $fieldsConfig;
}
- return $fieldsConfig;
- }
- ];
+ ];
+ }
return $typeConfig;
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Interfaces.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Interfaces.php
index 659c3f604508d..761ba68e44521 100644
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Interfaces.php
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Interfaces.php
@@ -8,7 +8,7 @@
namespace Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper\Formatter;
use Magento\Framework\GraphQl\Config\Element\Type;
-use Magento\Framework\GraphQl\Config\Element\TypeInterface;
+use Magento\Framework\GraphQl\Config\ConfigElementInterface;
use Magento\Framework\GraphQl\Schema\Type\OutputTypeInterface;
use Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper\FormatterInterface;
use Magento\Framework\GraphQl\Schema\Type\Output\OutputMapper;
@@ -32,9 +32,9 @@ public function __construct(OutputMapper $outputMapper)
}
/**
- * {@inheritDoc}
+ * @inheritDoc
*/
- public function format(TypeInterface $configElement, OutputTypeInterface $outputType) : array
+ public function format(ConfigElementInterface $configElement, OutputTypeInterface $outputType) : array
{
$config = [];
if ($configElement instanceof Type && !empty($configElement->getInterfaces())) {
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/ResolveType.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/ResolveType.php
index 3a40e609eb952..553e8fe40efc2 100644
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/ResolveType.php
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/ResolveType.php
@@ -8,7 +8,8 @@
namespace Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper\Formatter;
use Magento\Framework\GraphQl\Config\Element\InterfaceType;
-use Magento\Framework\GraphQl\Config\Element\TypeInterface;
+use Magento\Framework\GraphQl\Config\Element\UnionType;
+use Magento\Framework\GraphQl\Config\ConfigElementInterface;
use Magento\Framework\GraphQl\Schema\Type\OutputTypeInterface;
use Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper\FormatterInterface;
use Magento\Framework\ObjectManagerInterface;
@@ -32,12 +33,12 @@ public function __construct(ObjectManagerInterface $objectManager)
}
/**
- * {@inheritDoc}
+ * @inheritDoc
*/
- public function format(TypeInterface $configElement, OutputTypeInterface $outputType) : array
+ public function format(ConfigElementInterface $configElement, OutputTypeInterface $outputType) : array
{
$config = [];
- if ($configElement instanceof InterfaceType) {
+ if ($configElement instanceof InterfaceType || $configElement instanceof UnionType) {
$typeResolver = $this->objectManager->create($configElement->getTypeResolver());
$config['resolveType'] = function ($value) use ($typeResolver) {
return $typeResolver->resolveType($value);
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Unions.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Unions.php
new file mode 100644
index 0000000000000..75b6a58790a09
--- /dev/null
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Unions.php
@@ -0,0 +1,50 @@
+outputMapper = $outputMapper;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function format(ConfigElementInterface $configElement, OutputTypeInterface $outputType): array
+ {
+ $config = [];
+ if ($configElement instanceof UnionType && !empty($configElement->getTypes())) {
+ $unionTypes = [];
+ foreach ($configElement->getTypes() as $unionName) {
+ $unionTypes[$unionName] = $this->outputMapper->getOutputType($unionName);
+ }
+ $config['types'] = $unionTypes;
+ }
+
+ return $config;
+ }
+}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/FormatterComposite.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/FormatterComposite.php
index 416b4122b7097..c36df11012017 100644
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/FormatterComposite.php
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/FormatterComposite.php
@@ -7,11 +7,11 @@
namespace Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper;
-use Magento\Framework\GraphQl\Config\Element\TypeInterface;
+use Magento\Framework\GraphQl\Config\ConfigElementInterface;
use Magento\Framework\GraphQl\Schema\Type\OutputTypeInterface;
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
class FormatterComposite implements FormatterInterface
{
@@ -29,18 +29,19 @@ public function __construct(array $formatters)
}
/**
- * {@inheritDoc}
+ * @inheritDoc
*/
- public function format(TypeInterface $configElement, OutputTypeInterface $outputType) : array
+ public function format(ConfigElementInterface $configElement, OutputTypeInterface $outputType): array
{
- $config = [
+ $defaultConfig = [
'name' => $configElement->getName(),
'description' => $configElement->getDescription()
];
+ $formattedConfig = [];
foreach ($this->formatters as $formatter) {
- $config = array_merge($config, $formatter->format($configElement, $outputType));
+ $formattedConfig[] = $formatter->format($configElement, $outputType);
}
- return $config;
+ return array_merge($defaultConfig, ...$formattedConfig);
}
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/FormatterInterface.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/FormatterInterface.php
index 7d40b743a6a06..a99237aa8843a 100644
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/FormatterInterface.php
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/FormatterInterface.php
@@ -7,7 +7,7 @@
namespace Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper;
-use Magento\Framework\GraphQl\Config\Element\TypeInterface as TypeElementInterface;
+use Magento\Framework\GraphQl\Config\ConfigElementInterface;
use Magento\Framework\GraphQl\Schema\Type\OutputTypeInterface;
/**
@@ -18,9 +18,9 @@ interface FormatterInterface
/**
* Convert GraphQL config element to the object compatible with GraphQL schema generator.
*
- * @param TypeElementInterface $configElement
+ * @param ConfigElementInterface $configElement
* @param OutputTypeInterface $outputType
* @return array
*/
- public function format(TypeElementInterface $configElement, OutputTypeInterface $outputType) : array;
+ public function format(ConfigElementInterface $configElement, OutputTypeInterface $outputType): array;
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputMapper.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputMapper.php
index 046eeb5b1f93d..afe0d84de26f8 100644
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputMapper.php
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputMapper.php
@@ -13,7 +13,7 @@
use Magento\Framework\Phrase;
/**
- * Map type names to their output type/interface/enum classes.
+ * Map type names to their output type/interface/union/enum classes.
*/
class OutputMapper
{
@@ -38,7 +38,7 @@ public function __construct(
* @return OutputTypeInterface
* @throws GraphQlInputException
*/
- public function getOutputType($typeName)
+ public function getOutputType(string $typeName)
{
$outputType = $this->typeRegistry->get($typeName);
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputUnionObject.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputUnionObject.php
new file mode 100644
index 0000000000000..a63b7b7417527
--- /dev/null
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputUnionObject.php
@@ -0,0 +1,28 @@
+buildSchemaArray($configElement, $this));
+ }
+}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/UnionType.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/UnionType.php
new file mode 100644
index 0000000000000..a843c6c669acf
--- /dev/null
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/UnionType.php
@@ -0,0 +1,16 @@
+ $type) {
if (isset($type['implements'])
&& isset($type['implements'][$interface['name']])
@@ -253,7 +255,7 @@ private function convertInterfacesToAnnotations(string $graphQlSchemaContent): s
private function addPlaceHolderInSchema(string $graphQlSchemaContent) :string
{
$placeholderField = self::GRAPHQL_PLACEHOLDER_FIELD_NAME;
- $typesKindsPattern = '(type|interface|input)';
+ $typesKindsPattern = '(type|interface|input|union)';
$enumKindsPattern = '(enum)';
$typeNamePattern = '([_A-Za-z][_0-9A-Za-z]+)';
$typeDefinitionPattern = '([^\{]*)(\{[\s\t\n\r^\}]*\})';
@@ -328,13 +330,14 @@ private static function getModuleNameForRelevantFile(string $file): string
*/
private function addModuleNameToTypes(array $source, string $filePath): array
{
- foreach ($source as $typeName => $type) {
- if (!isset($type['module']) && (
- ($type['type'] === self::GRAPHQL_INTERFACE && isset($type['typeResolver']))
- || isset($type['implements'])
- )
- ) {
- $source[$typeName]['module'] = self::getModuleNameForRelevantFile($filePath);
+ foreach ($source as $typeName => $typeDefinition) {
+ if (!isset($typeDefinition['module'])) {
+ $hasTypeResolver = (bool)($typeDefinition['typeResolver'] ?? false);
+ $hasImplements = (bool)($typeDefinition['implements'] ?? false);
+ $typeDefinition = (bool)($typeDefinition['type'] ?? false);
+ if ((($typeDefinition === InterfaceType::GRAPHQL_INTERFACE && $hasTypeResolver) || $hasImplements)) {
+ $source[$typeName]['module'] = self::getModuleNameForRelevantFile($filePath);
+ }
}
}
diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/EnumType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/EnumType.php
index e4dec7afdab0a..c6e0481c7490e 100644
--- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/EnumType.php
+++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/EnumType.php
@@ -15,6 +15,8 @@
*/
class EnumType implements TypeMetaReaderInterface
{
+ public const GRAPHQL_ENUM = 'graphql_enum';
+
/**
* @var DocReader
*/
@@ -30,14 +32,14 @@ public function __construct(
}
/**
- * @inheritdoc
+ * @inheritDoc
*/
public function read(\GraphQL\Type\Definition\Type $typeMeta) : array
{
if ($typeMeta instanceof \GraphQL\Type\Definition\EnumType) {
$result = [
'name' => $typeMeta->name,
- 'type' => 'graphql_enum',
+ 'type' => self::GRAPHQL_ENUM,
'items' => [] // Populated later
];
foreach ($typeMeta->getValues() as $enumValueMeta) {
diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php
index 38159fac03b3b..2108a04d8a9ed 100644
--- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php
+++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php
@@ -17,6 +17,8 @@
*/
class InputObjectType implements TypeMetaReaderInterface
{
+ public const GRAPHQL_INPUT = 'graphql_input';
+
/**
* @var TypeMetaWrapperReader
*/
@@ -49,7 +51,7 @@ public function __construct(
}
/**
- * @inheritdoc
+ * @inheritDoc
*/
public function read(\GraphQL\Type\Definition\Type $typeMeta) : array
{
@@ -57,7 +59,7 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array
$typeName = $typeMeta->name;
$result = [
'name' => $typeName,
- 'type' => 'graphql_input',
+ 'type' => self::GRAPHQL_INPUT,
'fields' => [] // Populated later
];
$fields = $typeMeta->getFields();
diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php
index baadb4be61cf2..76550469d409e 100644
--- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php
+++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php
@@ -17,6 +17,8 @@
*/
class InterfaceType implements TypeMetaReaderInterface
{
+ public const GRAPHQL_INTERFACE = 'graphql_interface';
+
/**
* @var FieldMetaReader
*/
@@ -49,7 +51,7 @@ public function __construct(
}
/**
- * @inheritdoc
+ * @inheritDoc
*/
public function read(\GraphQL\Type\Definition\Type $typeMeta) : array
{
@@ -57,7 +59,7 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array
$typeName = $typeMeta->name;
$result = [
'name' => $typeName,
- 'type' => 'graphql_interface',
+ 'type' => self::GRAPHQL_INTERFACE,
'fields' => []
];
diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php
index ba8e46dd60557..3ad6d69eb5c9c 100644
--- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php
+++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php
@@ -19,6 +19,8 @@
*/
class ObjectType implements TypeMetaReaderInterface
{
+ public const GRAPHQL_TYPE = 'graphql_type';
+
/**
* @var FieldMetaReader
*/
@@ -69,7 +71,7 @@ public function __construct(
}
/**
- * @inheritdoc
+ * @inheritDoc
*/
public function read(\GraphQL\Type\Definition\Type $typeMeta) : array
{
@@ -77,7 +79,7 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array
$typeName = $typeMeta->name;
$result = [
'name' => $typeName,
- 'type' => 'graphql_type',
+ 'type' => self::GRAPHQL_TYPE,
'fields' => [], // Populated later
];
diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/UnionType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/UnionType.php
new file mode 100644
index 0000000000000..5776901765b5a
--- /dev/null
+++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/UnionType.php
@@ -0,0 +1,106 @@
+fieldMetaReader = $fieldMetaReader;
+ $this->docReader = $docReader;
+ $this->cacheAnnotationReader = $cacheAnnotationReader ?? \Magento\Framework\App\ObjectManager::getInstance()
+ ->get(CacheAnnotationReader::class);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function read(\GraphQL\Type\Definition\Type $typeMeta): array
+ {
+ if ($typeMeta instanceof \GraphQL\Type\Definition\UnionType) {
+ $typeName = $typeMeta->name;
+ $result = [
+ 'name' => $typeName,
+ 'type' => self::GRAPHQL_UNION,
+ 'types' => [],
+ ];
+
+ $unionTypeResolver = $this->getUnionTypeResolver($typeMeta);
+ if (!empty($unionTypeResolver)) {
+ $result['typeResolver'] = $unionTypeResolver;
+ }
+
+ foreach ($typeMeta->getTypes() as $type) {
+ $result['types'][] = $type->name;
+ }
+
+ if ($this->docReader->read($typeMeta->astNode->directives)) {
+ $result['description'] = $this->docReader->read($typeMeta->astNode->directives);
+ }
+
+ return $result;
+ } else {
+ return [];
+ }
+ }
+
+ /**
+ * Retrieve the union type resolver if it exists from the meta data
+ *
+ * @param \GraphQL\Type\Definition\UnionType $unionTypeMeta
+ * @return string
+ */
+ private function getUnionTypeResolver(\GraphQL\Type\Definition\UnionType $unionTypeMeta): string
+ {
+ /** @var \GraphQL\Language\AST\NodeList $directives */
+ $directives = $unionTypeMeta->astNode->directives;
+ foreach ($directives as $directive) {
+ if ($directive->name->value == 'typeResolver') {
+ foreach ($directive->arguments as $directiveArgument) {
+ if ($directiveArgument->name->value == 'class') {
+ return $directiveArgument->value->value;
+ }
+ }
+ }
+ }
+ return '';
+ }
+}
diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/TypeReaderComposite.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/TypeReaderComposite.php
index e9b899bb2bb5b..614c1e3a743a0 100644
--- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/TypeReaderComposite.php
+++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/TypeReaderComposite.php
@@ -25,7 +25,7 @@ public function __construct(
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function read(\GraphQL\Type\Definition\Type $typeMeta) : array
{