Skip to content

Commit 955d778

Browse files
authored
Merge pull request #753 from Simperfit/feature/728-show-in-out-in-swagger-doc
Support for normalization groups and filters in the Swagger doc
2 parents e2d3d42 + 94119bd commit 955d778

File tree

14 files changed

+1178
-290
lines changed

14 files changed

+1178
-290
lines changed

features/swagger/doc.feature

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,34 @@ Feature: Documentation support
1515
And the JSON node "info.title" should be equal to "My Dummy API"
1616
And the JSON node "info.description" should be equal to "This is a test API."
1717
# Supported classes
18+
And the Swagger class "AbstractDummy" exists
1819
And the Swagger class "CircularReference" exists
20+
And the Swagger class "CircularReference_a0dd2858dcb0d966f739c1ac906afa2e" exists
21+
And the Swagger class "CompositeItem" exists
22+
And the Swagger class "CompositeLabel" exists
23+
And the Swagger class "ConcreteDummy" exists
1924
And the Swagger class "CustomIdentifierDummy" exists
20-
And the Swagger class "CustomNormalizedDummy" exists
25+
And the Swagger class "CustomNormalizedDummy_601856395b57c6b15175297eb6c9890e" exists
26+
And the Swagger class "CustomNormalizedDummy_db9cba1a967111a02380774784c47722" exists
2127
And the Swagger class "CustomWritableIdentifierDummy" exists
2228
And the Swagger class "Dummy" exists
2329
And the Swagger class "RelatedDummy" exists
24-
And the Swagger class "RelationEmbedder" exists
30+
And the Swagger class "DummyTableInheritance" exists
31+
And the Swagger class "DummyTableInheritanceChild" exists
32+
And the Swagger class "OverriddenOperationDummy_441e1f98db3d0250bcb18dca087687c3" exists
33+
And the Swagger class "OverriddenOperationDummy_45f46ed6dc6f412229a8c12cd5583586" exists
34+
And the Swagger class "OverriddenOperationDummy_868796b9924a520acbb96f8b75dade9f" exists
35+
And the Swagger class "OverriddenOperationDummy_ff74003f36aebfe31c696fae1f701ae4" exists
36+
And the Swagger class "RelatedDummy" exists
37+
And the Swagger class "NoCollectionDummy" exists
38+
And the Swagger class "RelatedToDummyFriend" exists
39+
And the Swagger class "RelatedToDummyFriend_ad38b7a2760884e744c577a92e02b8c4" exists
40+
And the Swagger class "DummyFriend" exists
41+
And the Swagger class "RelationEmbedder_ced9cba177bf3134e609fccf878df9a7" exists
42+
And the Swagger class "RelationEmbedder_f02fd88a2291463447338402aee9a220" exists
43+
And the Swagger class "User_4320517091b72c69e9f0c72aac0141e8" exists
44+
And the Swagger class "User_7ce91261c0e731d95bb24b83b1f637b2" exists
45+
And the Swagger class "UuidIdentifierDummy" exists
2546
And the Swagger class "ThirdLevel" exists
2647
And the Swagger class "ParentDummy" doesn't exist
2748
And the Swagger class "UnknownDummy" doesn't exist
@@ -30,10 +51,14 @@ Feature: Documentation support
3051
And the Swagger path "/api/custom-call/{id}" exists
3152
And the JSON node "paths./api/custom-call/{id}.get" should exist
3253
And the JSON node "paths./api/custom-call/{id}.put" should exist
33-
3454
# Properties
3555
And "id" property exists for the Swagger class "Dummy"
3656
And "name" property is required for Swagger class "Dummy"
57+
# Filters
58+
And the JSON node "paths./dummies.get.parameters[0].name" should be equal to "id"
59+
And the JSON node "paths./dummies.get.parameters[0].in" should be equal to "query"
60+
And the JSON node "paths./dummies.get.parameters[0].required" should be false
61+
And the JSON node "paths./dummies.get.parameters[0].type" should be equal to "integer"
3762

3863
Scenario: Swagger UI is enabled for the doc endpoint
3964
Given I add "Accept" header equal to "text/html"

src/Bridge/Doctrine/Orm/Filter/BooleanFilter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function getDescription(string $resourceClass) : array
5757

5858
$description[$property] = [
5959
'property' => $property,
60-
'type' => 'boolean',
60+
'type' => 'bool',
6161
'required' => false,
6262
];
6363
}

src/Bridge/Doctrine/Orm/Filter/DateFilter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ protected function getFilterDescription(string $property, string $period) : arra
194194
return [
195195
sprintf('%s[%s]', $property, $period) => [
196196
'property' => $property,
197-
'type' => '\DateTime',
197+
'type' => \DateTimeInterface::class,
198198
'required' => false,
199199
],
200200
];

src/Bridge/Doctrine/Orm/Filter/NumericFilter.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,34 @@ public function getDescription(string $resourceClass) : array
7171

7272
$description[$property] = [
7373
'property' => $property,
74-
'type' => $metadata->getTypeOfField($propertyParts['field']),
74+
'type' => $this->getType($metadata->getTypeOfField($propertyParts['field'])),
7575
'required' => false,
7676
];
7777
}
7878

7979
return $description;
8080
}
8181

82+
/**
83+
* Gets the PHP type corresponding to this Doctrine type.
84+
*
85+
* @param string $doctrineType
86+
*
87+
* @return string
88+
*/
89+
private function getType(string $doctrineType) : string
90+
{
91+
if (DBALType::DECIMAL === $doctrineType) {
92+
return 'string';
93+
}
94+
95+
if (DBALType::FLOAT === $doctrineType) {
96+
return 'float';
97+
}
98+
99+
return 'int';
100+
}
101+
82102
/**
83103
* {@inheritdoc}
84104
*/

src/Bridge/Doctrine/Orm/Filter/SearchFilter.php

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
1616
use ApiPlatform\Core\Exception\InvalidArgumentException;
1717
use Doctrine\Common\Persistence\ManagerRegistry;
18+
use Doctrine\DBAL\Types\Type;
1819
use Doctrine\ORM\QueryBuilder;
1920
use Psr\Log\LoggerInterface;
2021
use Symfony\Component\HttpFoundation\RequestStack;
@@ -91,14 +92,14 @@ public function getDescription(string $resourceClass) : array
9192
}
9293

9394
if ($metadata->hasField($field)) {
94-
$typeOfField = $metadata->getTypeOfField($field);
95+
$typeOfField = $this->getType($metadata->getTypeOfField($field));
9596
$strategy = $this->properties[$property] ?? self::STRATEGY_EXACT;
96-
$filterParameterNames = [
97-
$property,
98-
];
97+
$filterParameterNames = [$property];
98+
9999
if (self::STRATEGY_EXACT === $strategy) {
100100
$filterParameterNames[] = $property.'[]';
101101
}
102+
102103
foreach ($filterParameterNames as $filterParameterName) {
103104
$description[$filterParameterName] = [
104105
'property' => $property,
@@ -116,7 +117,7 @@ public function getDescription(string $resourceClass) : array
116117
foreach ($filterParameterNames as $filterParameterName) {
117118
$description[$filterParameterName] = [
118119
'property' => $property,
119-
'type' => 'iri',
120+
'type' => 'string',
120121
'required' => false,
121122
'strategy' => self::STRATEGY_EXACT,
122123
];
@@ -127,6 +128,40 @@ public function getDescription(string $resourceClass) : array
127128
return $description;
128129
}
129130

131+
/**
132+
* Converts a Doctrine type in PHP type.
133+
*
134+
* @param string $doctrineType
135+
*
136+
* @return string
137+
*/
138+
private function getType(string $doctrineType) : string
139+
{
140+
switch ($doctrineType) {
141+
case Type::TARRAY:
142+
return 'array';
143+
144+
case Type::BIGINT:
145+
case Type::INTEGER:
146+
case Type::SMALLINT:
147+
return 'int';
148+
149+
case Type::BOOLEAN:
150+
return 'bool';
151+
152+
case Type::DATE:
153+
case Type::TIME:
154+
case Type::DATETIME:
155+
case Type::DATETIMETZ:
156+
return \DateTimeInterface::class;
157+
158+
case Type::FLOAT:
159+
return 'float';
160+
}
161+
162+
return 'string';
163+
}
164+
130165
/**
131166
* {@inheritdoc}
132167
*/

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<argument type="service" id="api_platform.operation_method_resolver" />
1515
<argument type="service" id="api_platform.operation_path_resolver" />
1616
<argument type="service" id="api_platform.router" />
17+
<argument type="service" id="api_platform.filters" />
1718

1819
<tag name="serializer.normalizer" priority="16" />
1920
</service>

src/Hydra/Serializer/CollectionFiltersNormalizer.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ public function normalize($object, $format = null, array $context = [])
6363
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
6464

6565
$operationName = $context['collection_operation_name'] ?? null;
66-
6766
if (null === $operationName) {
6867
$resourceFilters = $resourceMetadata->getAttribute('filters', []);
6968
} else {

0 commit comments

Comments
 (0)