forked from api-platform/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[GraphQL] Embedded entities support for mutations (api-platform#1765)
* Add InputUnionType * Use InputUnionType for embedded entities * Use InputUnionType for updating related existing resources * Remove final from ItemNormalizer (add a PHPDoc final instead)
- Loading branch information
1 parent
90a61ab
commit d7ada1b
Showing
6 changed files
with
465 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,13 +23,14 @@ | |
|
||
use ApiPlatform\Core\Metadata\Property\PropertyMetadata; | ||
use ApiPlatform\Core\Serializer\AbstractItemNormalizer; | ||
use ApiPlatform\Core\Serializer\ItemNormalizer as GenericItemNormalizer; | ||
|
||
/** | ||
* GraphQL normalizer. | ||
* | ||
* @author Kévin Dunglas <[email protected]> | ||
*/ | ||
final class ItemNormalizer extends AbstractItemNormalizer | ||
final class ItemNormalizer extends GenericItemNormalizer | ||
{ | ||
const FORMAT = 'graphql'; | ||
const ITEM_KEY = '#item'; | ||
|
@@ -39,7 +40,7 @@ final class ItemNormalizer extends AbstractItemNormalizer | |
*/ | ||
public function normalize($object, $format = null, array $context = []) | ||
{ | ||
$data = parent::normalize($object, $format, $context); | ||
$data = AbstractItemNormalizer::normalize($object, $format, $context); | ||
$data[self::ITEM_KEY] = serialize($object); // calling serialize prevent weird normalization process done by Webonyx's GraphQL PHP | ||
|
||
return $data; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the API Platform project. | ||
* | ||
* (c) Kévin Dunglas <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace ApiPlatform\Core\GraphQl\Type\Definition; | ||
|
||
use GraphQL\Error\Error; | ||
use GraphQL\Error\InvariantViolation; | ||
use GraphQL\Type\Definition\InputObjectType; | ||
use GraphQL\Type\Definition\InputType; | ||
use GraphQL\Type\Definition\LeafType; | ||
use GraphQL\Type\Definition\Type; | ||
use GraphQL\Utils\Utils; | ||
|
||
/** | ||
* Represents an union of other input types. | ||
* | ||
* @experimental | ||
* | ||
* @author Alan Poulain <[email protected]> | ||
*/ | ||
final class InputUnionType extends Type implements InputType, LeafType | ||
{ | ||
/** | ||
* @var InputObjectType[] | ||
*/ | ||
private $types; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private $config; | ||
|
||
/** | ||
* @throws InvariantViolation | ||
*/ | ||
public function __construct(array $config) | ||
{ | ||
if (!isset($config['name'])) { | ||
$config['name'] = $this->tryInferName(); | ||
} | ||
|
||
Utils::assertValidName($config['name']); | ||
|
||
$this->name = $config['name']; | ||
$this->description = $config['description'] ?? null; | ||
$this->config = $config; | ||
} | ||
|
||
/** | ||
* @throws InvariantViolation | ||
* | ||
* @return InputObjectType[] | ||
*/ | ||
public function getTypes(): array | ||
{ | ||
if (null !== $this->types) { | ||
return $this->types; | ||
} | ||
|
||
if (($types = $this->config['types'] ?? null) && \is_callable($types)) { | ||
$types = \call_user_func($this->config['types']); | ||
} | ||
|
||
if (!\is_array($types)) { | ||
throw new InvariantViolation( | ||
"{$this->name} types must be an Array or a callable which returns an Array." | ||
); | ||
} | ||
|
||
return $this->types = $types; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function assertValid() | ||
{ | ||
parent::assertValid(); | ||
|
||
$types = $this->getTypes(); | ||
Utils::invariant(\count($types) > 0, "{$this->name} types must not be empty"); | ||
|
||
$includedTypeNames = []; | ||
foreach ($types as $inputType) { | ||
Utils::invariant( | ||
$inputType instanceof InputType, | ||
"{$this->name} may only contain input types, it cannot contain: %s.", | ||
Utils::printSafe($inputType) | ||
); | ||
Utils::invariant( | ||
!isset($includedTypeNames[$inputType->name]), | ||
"{$this->name} can include {$inputType->name} type only once." | ||
); | ||
$includedTypeNames[$inputType->name] = true; | ||
} | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @throws InvariantViolation | ||
*/ | ||
public function serialize($value) | ||
{ | ||
foreach ($this->getTypes() as $type) { | ||
if ($type instanceof LeafType) { | ||
try { | ||
return $type->serialize($value); | ||
} catch (\Exception $e) { | ||
} | ||
} | ||
} | ||
|
||
throw new InvariantViolation(sprintf('Types in union cannot represent value: %s', Utils::printSafe($value))); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @throws Error | ||
*/ | ||
public function parseValue($value) | ||
{ | ||
foreach ($this->getTypes() as $type) { | ||
if ($type instanceof LeafType) { | ||
try { | ||
return $type->parseValue($value); | ||
} catch (\Exception $e) { | ||
} | ||
} | ||
} | ||
|
||
throw new Error(sprintf('Types in union cannot represent value: %s', Utils::printSafeJson($value))); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function parseLiteral($valueNode) | ||
{ | ||
foreach ($this->getTypes() as $type) { | ||
if ($type instanceof LeafType && null !== $parsed = $type->parseLiteral($valueNode)) { | ||
return $parsed; | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function isValidValue($value): bool | ||
{ | ||
foreach ($this->getTypes() as $type) { | ||
if ($type instanceof LeafType && $type->isValidValue($value)) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function isValidLiteral($valueNode): bool | ||
{ | ||
foreach ($this->getTypes() as $type) { | ||
if ($type instanceof LeafType && $type->isValidLiteral($valueNode)) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,9 +18,11 @@ | |
/** | ||
* Generic item normalizer. | ||
* | ||
* @final | ||
* | ||
* @author Kévin Dunglas <[email protected]> | ||
*/ | ||
final class ItemNormalizer extends AbstractItemNormalizer | ||
class ItemNormalizer extends AbstractItemNormalizer | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
|
Oops, something went wrong.