Skip to content

Commit 1c4b5f8

Browse files
committed
Use InputUnionType for embedded entities
1 parent 2a27f50 commit 1c4b5f8

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

features/graphql/mutation.feature

+16
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,22 @@ Feature: GraphQL mutation support
106106
And the JSON node "data.createDummy.arrayData[1]" should be equal to baz
107107
And the JSON node "data.createDummy.clientMutationId" should be equal to "myId"
108108

109+
Scenario: Create an item with an embedded field
110+
When I send the following GraphQL request:
111+
"""
112+
mutation {
113+
createRelatedDummy(input: {_id: 2, symfony: "symfony", embeddedDummy: {dummyName: "Embedded"}, clientMutationId: "myId"}) {
114+
id
115+
clientMutationId
116+
}
117+
}
118+
"""
119+
Then the response status code should be 200
120+
And the response should be in JSON
121+
And the header "Content-Type" should be equal to "application/json"
122+
And the JSON node "data.createRelatedDummy.id" should be equal to "/related_dummies/2"
123+
And the JSON node "data.createRelatedDummy.clientMutationId" should be equal to "myId"
124+
109125
@dropSchema
110126
Scenario: Delete an item through a mutation
111127
When I send the following GraphQL request:

src/GraphQl/Type/SchemaBuilder.php

+26-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use ApiPlatform\Core\Exception\ResourceClassNotFoundException;
1717
use ApiPlatform\Core\GraphQl\Resolver\Factory\ResolverFactoryInterface;
1818
use ApiPlatform\Core\GraphQl\Serializer\ItemNormalizer;
19+
use ApiPlatform\Core\GraphQl\Type\Definition\InputUnionType;
1920
use ApiPlatform\Core\GraphQl\Type\Definition\IterableType;
2021
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
2122
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
@@ -335,13 +336,24 @@ private function convertType(Type $type, bool $input = false, string $mutationNa
335336
break;
336337
case Type::BUILTIN_TYPE_ARRAY:
337338
case Type::BUILTIN_TYPE_ITERABLE:
338-
if (!isset($this->graphqlTypes['#iterable'])) {
339-
$this->graphqlTypes['#iterable'] = new IterableType();
340-
}
341-
$graphqlType = $this->graphqlTypes['#iterable'];
339+
$graphqlType = $this->getIterableType();
342340
break;
343341
case Type::BUILTIN_TYPE_OBJECT:
344-
if (($input && $depth > 0) || is_a($type->getClassName(), \DateTimeInterface::class, true)) {
342+
if ($input && $depth > 0) {
343+
if (!isset($this->graphqlTypes['#stringIterableUnionInput'])) {
344+
$this->graphqlTypes['#stringIterableUnionInput'] = new InputUnionType([
345+
'name' => 'StringIterableUnionInput',
346+
'description' => 'Resource\'s IRI or data (embedded entities or when updating a related existing resource)',
347+
'types' => [
348+
GraphQLType::string(),
349+
$this->getIterableType(),
350+
],
351+
]);
352+
}
353+
$graphqlType = $this->graphqlTypes['#stringIterableUnionInput'];
354+
break;
355+
}
356+
if (is_a($type->getClassName(), \DateTimeInterface::class, true)) {
345357
$graphqlType = GraphQLType::string();
346358
break;
347359
}
@@ -492,6 +504,15 @@ private function getResourcePaginatedCollectionType(string $resourceClass, Graph
492504
return $this->graphqlTypes[$resourceClass]['connection'] = new ObjectType($configuration);
493505
}
494506

507+
private function getIterableType(): IterableType
508+
{
509+
if (!isset($this->graphqlTypes['#iterable'])) {
510+
$this->graphqlTypes['#iterable'] = new IterableType();
511+
}
512+
513+
return $this->graphqlTypes['#iterable'];
514+
}
515+
495516
private function isCollection(Type $type): bool
496517
{
497518
return $type->isCollection() && Type::BUILTIN_TYPE_OBJECT === $type->getBuiltinType();

0 commit comments

Comments
 (0)