Skip to content

Commit 796f613

Browse files
authored
[GraphQL] Services Refactoring (#2772)
* Add a TypeConverter to manage custom types * Fix PHPStan
1 parent 1d5f020 commit 796f613

25 files changed

+2392
-795
lines changed

features/graphql/collection.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ Feature: GraphQL collection support
113113
And the response should be in JSON
114114
And the header "Content-Type" should be equal to "application/json"
115115
And the JSON node "data.dummies.edges[1].node.name" should be equal to "Dummy #2"
116-
And the JSON node "data.dummies.edges[1].node.dummyDate" should be equal to "2015-04-02T00:00:00+00:00"
116+
And the JSON node "data.dummies.edges[1].node.dummyDate" should be equal to "2015-04-02"
117117
And the JSON node "data.dummyGroup.foo" should be equal to "Foo #2"
118118

119119
@createSchema

features/graphql/filters.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Feature: Collections filtering
6363
}
6464
"""
6565
Then the JSON node "data.dummies.edges" should have 1 element
66-
And the JSON node "data.dummies.edges[0].node.dummyDate" should be equal to "2015-04-02T00:00:00+00:00"
66+
And the JSON node "data.dummies.edges[0].node.dummyDate" should be equal to "2015-04-02"
6767

6868
@createSchema
6969
Scenario: Retrieve a collection filtered using the search filter

features/graphql/mutation.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ Feature: GraphQL mutation support
228228
And the JSON node "data.updateDummy.dummy.id" should be equal to "/dummies/1"
229229
And the JSON node "data.updateDummy.dummy.name" should be equal to "Dummy #1"
230230
And the JSON node "data.updateDummy.dummy.description" should be equal to "Modified description."
231-
And the JSON node "data.updateDummy.dummy.dummyDate" should be equal to "2018-06-05T00:00:00+00:00"
231+
And the JSON node "data.updateDummy.dummy.dummyDate" should be equal to "2018-06-05"
232232
And the JSON node "data.updateDummy.dummy.relatedDummies.edges[0].node.name" should be equal to "RelatedDummy11"
233233
And the JSON node "data.updateDummy.clientMutationId" should be equal to "myId"
234234

features/graphql/type.feature

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
Feature: GraphQL type support
2+
@createSchema
3+
Scenario: Use a custom type for a field
4+
Given there are 2 dummy objects with dummyDate
5+
When I send the following GraphQL request:
6+
"""
7+
{
8+
dummy(id: "/dummies/1") {
9+
dummyDate
10+
}
11+
}
12+
"""
13+
Then the response status code should be 200
14+
And the response should be in JSON
15+
And the header "Content-Type" should be equal to "application/json"
16+
And the JSON node "data.dummy.dummyDate" should be equal to "2015-04-01"
17+
18+
Scenario: Use a custom type for an input field
19+
When I send the following GraphQL request:
20+
"""
21+
mutation {
22+
updateDummy(input: {id: "/dummies/1", dummyDate: "2019-05-24T00:00:00+00:00"}) {
23+
dummy {
24+
dummyDate
25+
}
26+
}
27+
}
28+
"""
29+
Then the response status code should be 200
30+
And the response should be in JSON
31+
And the header "Content-Type" should be equal to "application/json"
32+
And the JSON node "data.updateDummy.dummy.dummyDate" should be equal to "2019-05-24"
33+
34+
Scenario: Use a custom type for a query variable
35+
When I have the following GraphQL request:
36+
"""
37+
mutation UpdateDummyDate($itemId: ID!, $itemDate: DateTime!) {
38+
updateDummy(input: {id: $itemId, dummyDate: $itemDate}) {
39+
dummy {
40+
dummyDate
41+
}
42+
}
43+
}
44+
"""
45+
And I send the GraphQL request with variables:
46+
"""
47+
{
48+
"itemId": "/dummies/1",
49+
"itemDate": "2017-11-14T00:00:00+00:00"
50+
}
51+
"""
52+
Then the response status code should be 200
53+
And the response should be in JSON
54+
And the header "Content-Type" should be equal to "application/json"
55+
And the JSON node "data.updateDummy.dummy.dummyDate" should be equal to "2017-11-14"
56+
57+
Scenario: Use a custom type for a query variable and use a bad value
58+
When I have the following GraphQL request:
59+
"""
60+
mutation UpdateDummyDate($itemId: ID!, $itemDate: DateTime!) {
61+
updateDummy(input: {id: $itemId, dummyDate: $itemDate}) {
62+
dummy {
63+
dummyDate
64+
}
65+
}
66+
}
67+
"""
68+
And I send the GraphQL request with variables:
69+
"""
70+
{
71+
"itemId": "/dummies/1",
72+
"itemDate": "bad date"
73+
}
74+
"""
75+
Then the response status code should be 200
76+
And the response should be in JSON
77+
And the header "Content-Type" should be equal to "application/json"
78+
And the JSON node "errors[0].message" should be equal to 'Variable "$itemDate" got invalid value "bad date"; Expected type DateTime; DateTime cannot represent non date value: "bad date"'

phpstan.neon.dist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,15 @@ parameters:
7676
-
7777
message: '#Binary operation "\+" between (float\|int\|)?string and 0 results in an error\.#'
7878
path: %currentWorkingDirectory%/src/Bridge/Doctrine/Common/Filter/RangeFilterTrait.php
79+
- '#Parameter \#1 \$objectValue of method GraphQL\\Type\\Definition\\InterfaceType::resolveType\(\) expects object, array(<string, string>)? given.#'
7980

8081
# Expected, due to deprecations
8182
- '#Method ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Extension\\QueryResult(Item|Collection)ExtensionInterface::getResult\(\) invoked with 4 parameters, 1 required\.#'
8283
- '#Method ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Extension\\QueryResult(Item|Collection)ExtensionInterface::supportsResult\(\) invoked with 3 parameters, 1-2 required\.#'
8384
- '#Method ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Filter\\AbstractFilter::apply\(\) invoked with 5 parameters, 3-4 required\.#'
8485
- '#Method ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Filter\\AbstractFilter::filterProperty\(\) invoked with 7 parameters, 5-6 required\.#'
8586
- '#Method ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Filter\\FilterInterface::apply\(\) invoked with 5 parameters, 3-4 required\.#'
87+
- '#Method ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Filter\\ExistsFilter::filterProperty\(\) invoked with 7 parameters, 5-6 required\.#'
8688
- '#Method ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Filter\\OrderFilter::filterProperty\(\) invoked with 7 parameters, 5-6 required\.#'
8789
- '#Method ApiPlatform\\Core\\DataProvider\\CollectionDataProviderInterface::getCollection\(\) invoked with 3 parameters, 1-2 required\.#'
8890
- '#Method Symfony\\Component\\Serializer\\NameConverter\\NameConverterInterface::normalize\(\) invoked with 3 parameters, 1 required\.#'

src/Bridge/Symfony/Bundle/Resources/config/graphql.xml

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,24 +60,52 @@
6060
<tag name="container.service_locator" />
6161
</service>
6262

63+
<service id="api_platform.graphql.types_container" class="ApiPlatform\Core\GraphQl\Type\TypesContainer" />
64+
6365
<service id="api_platform.graphql.types_factory" class="ApiPlatform\Core\GraphQl\Type\TypesFactory">
6466
<argument type="service" id="api_platform.graphql.type_locator" />
6567
</service>
6668

67-
<service id="api_platform.graphql.schema_builder" class="ApiPlatform\Core\GraphQl\Type\SchemaBuilder" public="false">
69+
<service id="api_platform.graphql.type_converter" class="ApiPlatform\Core\GraphQl\Type\TypeConverter">
70+
<argument type="service" id="api_platform.graphql.type_builder" />
71+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
72+
</service>
73+
74+
<service id="api_platform.graphql.type_builder" class="ApiPlatform\Core\GraphQl\Type\TypeBuilder" public="false">
75+
<argument type="service" id="api_platform.graphql.types_container" />
76+
<argument type="service" id="api_platform.graphql.resolver.resource_field" />
77+
<argument type="service" id="api_platform.graphql.fields_builder_locator" />
78+
</service>
79+
80+
<service id="api_platform.graphql.fields_builder" class="ApiPlatform\Core\GraphQl\Type\FieldsBuilder" public="false">
6881
<argument type="service" id="api_platform.metadata.property.name_collection_factory" />
6982
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
70-
<argument type="service" id="api_platform.metadata.resource.name_collection_factory" />
7183
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
84+
<argument type="service" id="api_platform.graphql.types_container" />
85+
<argument type="service" id="api_platform.graphql.type_builder" />
86+
<argument type="service" id="api_platform.graphql.type_converter" />
7287
<argument type="service" id="api_platform.graphql.resolver.factory.item" />
7388
<argument type="service" id="api_platform.graphql.resolver.factory.collection" />
7489
<argument type="service" id="api_platform.graphql.resolver.factory.item_mutation" />
75-
<argument type="service" id="api_platform.graphql.resolver.resource_field" />
76-
<argument type="service" id="api_platform.graphql.types_factory" />
7790
<argument type="service" id="api_platform.filter_locator" />
7891
<argument>%api_platform.collection.pagination.enabled%</argument>
7992
</service>
8093

94+
<service id="api_platform.graphql.fields_builder_locator" class="Symfony\Component\DependencyInjection\ServiceLocator" public="false">
95+
<argument type="collection">
96+
<argument type="service" id="api_platform.graphql.fields_builder" />
97+
</argument>
98+
<tag name="container.service_locator"/>
99+
</service>
100+
101+
<service id="api_platform.graphql.schema_builder" class="ApiPlatform\Core\GraphQl\Type\SchemaBuilder" public="false">
102+
<argument type="service" id="api_platform.metadata.resource.name_collection_factory" />
103+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
104+
<argument type="service" id="api_platform.graphql.types_factory" />
105+
<argument type="service" id="api_platform.graphql.types_container" />
106+
<argument type="service" id="api_platform.graphql.fields_builder" />
107+
</service>
108+
81109
<!-- Action -->
82110

83111
<service id="api_platform.graphql.action.entrypoint" class="ApiPlatform\Core\GraphQl\Action\EntrypointAction" public="true">

0 commit comments

Comments
 (0)