Skip to content

Commit 6def19c

Browse files
author
Amrouche Hamza
committed
feature: add swagger v2
1 parent 2d972c0 commit 6def19c

File tree

23 files changed

+1132
-25
lines changed

23 files changed

+1132
-25
lines changed

src/Bridge/NelmioApiDoc/Extractor/AnnotationsProvider/ApiPlatformProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
use ApiPlatform\Core\Api\FilterCollection;
1515
use ApiPlatform\Core\Bridge\NelmioApiDoc\Parser\ApiPlatformParser;
1616
use ApiPlatform\Core\Bridge\Symfony\Routing\OperationMethodResolverInterface;
17-
use ApiPlatform\Core\Hydra\ApiDocumentationBuilderInterface;
1817
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
1918
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceNameCollectionFactoryInterface;
2019
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
20+
use ApiPlatform\Core\Util\ApiDocumentationBuilderInterface;
2121
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
2222
use Nelmio\ApiDocBundle\Extractor\AnnotationsProviderInterface;
2323
use Symfony\Component\HttpFoundation\Request;

src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,15 @@ public function load(array $configs, ContainerBuilder $container)
110110
}
111111

112112
/**
113-
* Enables JSON-LD and Hydra support.
113+
* Enables JSON-LD and Hydra and Swagger support.
114114
*
115115
* @param XmlFileLoader $loader
116116
*/
117117
private function enableJsonLd(XmlFileLoader $loader)
118118
{
119119
$loader->load('jsonld.xml');
120120
$loader->load('hydra.xml');
121+
$loader->load('swagger.xml');
121122
}
122123

123124
/**

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<tag name="kernel.event_listener" event="kernel.response" method="onKernelResponse" />
2828
</service>
2929

30-
<service id="api_platform.hydra.listener.validation_exception" class="ApiPlatform\Core\Bridge\Symfony\Validator\Hydra\EventListener\ValidationExceptionListener">
30+
<service id="api_platform.hydra.listener.validation_exception" class="ApiPlatform\Core\Bridge\Symfony\Validator\Hydra\EventListener\HydraExceptionListener">
3131
<argument type="service" id="api_platform.hydra.normalizer.constraint_violation_list" />
3232

3333
<tag name="kernel.event_listener" event="kernel.exception" method="onKernelException" />
@@ -51,7 +51,7 @@
5151
<tag name="serializer.normalizer" priority="50" />
5252
</service>
5353

54-
<service id="api_platform.hydra.normalizer.constraint_violation_list" class="ApiPlatform\Core\Bridge\Symfony\Validator\Hydra\Serializer\ConstraintViolationListNormalizer" public="false">
54+
<service id="api_platform.hydra.normalizer.constraint_violation_list" class="ApiPlatform\Core\Bridge\Symfony\Validator\Serializer\ConstraintViolationListNormalizer" public="false">
5555
<argument type="service" id="api_platform.router" />
5656

5757
<tag name="serializer.normalizer" />
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<routes xmlns="http://symfony.com/schema/routing"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/routing
6+
http://symfony.com/schema/routing/routing-1.0.xsd">
7+
8+
<route id="api_swagger_vocab" path="/swagger.json">
9+
<default key="_controller">api_platform.swagger.action.documentation</default>
10+
</route>
11+
</routes>
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
6+
7+
<services>
8+
9+
<service id="api_platform.swagger.documentation_builder" class="ApiPlatform\Core\Swagger\ApiDocumentationBuilder" public="false">
10+
<argument type="service" id="api_platform.metadata.resource.name_collection_factory" />
11+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
12+
<argument type="service" id="api_platform.metadata.property.name_collection_factory" />
13+
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
14+
<argument type="service" id="api_platform.jsonld.context_builder" />
15+
<argument type="service" id="api_platform.resource_class_resolver" />
16+
<argument type="service" id="api_platform.operation_method_resolver" />
17+
<argument type="service" id="api_platform.router" />
18+
<argument type="service" id="api_platform.iri_converter" />
19+
<argument>%api_platform.title%</argument>
20+
<argument>%api_platform.description%</argument>
21+
</service>
22+
23+
<!-- Event listeners -->
24+
25+
<service id="api_platform.swagger.listener.link_header_response" class="ApiPlatform\Core\Swagger\EventListener\SwaggerLinkHeaderResponseListener">
26+
<argument type="service" id="api_platform.router" />
27+
28+
<tag name="kernel.event_listener" event="kernel.response" method="onKernelResponse" />
29+
</service>
30+
31+
<service id="api_platform.hydra.listener.validation_exception" class="ApiPlatform\Core\Bridge\Symfony\Validator\Swagger\EventListener\SwaggerValidationExceptionListener">
32+
<argument type="service" id="api_platform.hydra.normalizer.constraint_violation_list" />
33+
34+
<tag name="kernel.event_listener" event="kernel.exception" method="onKernelException" />
35+
</service>
36+
37+
<service id="api_platform.swagger.listener.request_exception" class="ApiPlatform\Core\Swagger\EventListener\RequestExceptionListener">
38+
<argument>api_platform.hydra.action.exception</argument>
39+
<argument type="service" id="logger" on-invalid="null" />
40+
41+
<tag name="kernel.event_listener" event="kernel.exception" method="onKernelException" priority="-96" />
42+
<tag name="monolog.logger" channel="request" />
43+
</service>
44+
45+
<!-- Serializer -->
46+
47+
<service id="api_platform.swagger.normalizer.collection" class="ApiPlatform\Core\Swagger\Serializer\CollectionNormalizer" public="false">
48+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
49+
<argument type="service" id="api_platform.jsonld.context_builder" />
50+
<argument type="service" id="api_platform.resource_class_resolver" />
51+
<argument type="service" id="api_platform.iri_converter" />
52+
53+
<tag name="serializer.normalizer" priority="50" />
54+
</service>
55+
56+
<service id="api_platform.swagger.normalizer.constraint_violation_list" class="ApiPlatform\Core\Bridge\Symfony\Validator\Serializer\ConstraintViolationListNormalizer" public="false">
57+
<argument type="service" id="api_platform.router" />
58+
59+
<tag name="serializer.normalizer" />
60+
</service>
61+
62+
<service id="api_platform.swagger.normalizer.error" class="ApiPlatform\Core\Swagger\Serializer\SwaggerErrorNormalizer" public="false">
63+
<argument type="service" id="api_platform.router" />
64+
<argument>%kernel.debug%</argument>
65+
66+
<tag name="serializer.normalizer" />
67+
</service>
68+
69+
<service id="api_platform.swagger.normalizer.partial_collection_view" class="ApiPlatform\Core\Swagger\Serializer\PartialCollectionViewNormalizer" decorates="api_platform.hydra.normalizer.collection" public="false">
70+
<argument type="service" id="api_platform.swagger.normalizer.partial_collection_view.inner" />
71+
<argument>%api_platform.collection.pagination.page_parameter_name%</argument>
72+
<argument>%api_platform.collection.pagination.enabled_parameter_name%</argument>
73+
</service>
74+
75+
<service id="api_platform.swagger.normalizer.collection_filters" class="ApiPlatform\Core\Swagger\Serializer\CollectionFiltersNormalizer" decorates="api_platform.hydra.normalizer.collection" public="false">
76+
<argument type="service" id="api_platform.swagger.normalizer.collection_filters.inner" />
77+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
78+
<argument type="service" id="api_platform.resource_class_resolver" />
79+
<argument type="service" id="api_platform.filters" />
80+
</service>
81+
82+
<!-- Action -->
83+
84+
<service id="api_platform.swagger.action.documentation" class="ApiPlatform\Core\Swagger\Action\DocumentationAction">
85+
<argument type="service" id="api_platform.swagger.documentation_builder" />
86+
</service>
87+
88+
<service id="api_platform.swagger.action.exception" class="ApiPlatform\Core\Swagger\Action\ExceptionAction">
89+
<argument type="service" id="api_platform.swagger.normalizer.error" />
90+
</service>
91+
92+
</services>
93+
94+
</container>

src/Bridge/Symfony/Routing/ApiLoader.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public function load($data, $type = null)
5959

6060
$routeCollection->addCollection($this->fileLoader->load('jsonld.xml'));
6161
$routeCollection->addCollection($this->fileLoader->load('hydra.xml'));
62+
$routeCollection->addCollection($this->fileLoader->load('swagger.xml'));
6263

6364
foreach ($this->resourceNameCollectionFactory->create() as $resourceClass) {
6465
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);

src/Bridge/Symfony/Validator/Hydra/EventListener/ValidationExceptionListener.php renamed to src/Bridge/Symfony/Validator/Hydra/EventListener/HydraValidationExceptionListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
*
2222
* @author Kévin Dunglas <[email protected]>
2323
*/
24-
final class ValidationExceptionListener
24+
final class HydraValidationExceptionListener
2525
{
2626
private $normalizer;
2727

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace ApiPlatform\Core\Bridge\Symfony\Validator\Hydra\Serializer;
12+
namespace ApiPlatform\Core\Bridge\Symfony\Validator\Serializer;
1313

1414
use ApiPlatform\Core\Api\UrlGeneratorInterface;
1515
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
@@ -22,7 +22,7 @@
2222
*/
2323
final class ConstraintViolationListNormalizer implements NormalizerInterface
2424
{
25-
const FORMAT = 'hydra-error';
25+
const FORMAT = ['swagger-error', 'hydra-error'];
2626

2727
/**
2828
* @var UrlGeneratorInterface
@@ -41,12 +41,11 @@ public function normalize($object, $format = null, array $context = [])
4141
{
4242
$violations = [];
4343
$messages = [];
44-
4544
foreach ($object as $violation) {
4645
$violations[] = [
47-
'propertyPath' => $violation->getPropertyPath(),
48-
'message' => $violation->getMessage(),
49-
];
46+
'propertyPath' => $violation->getPropertyPath(),
47+
'message' => $violation->getMessage(),
48+
];
5049

5150
$propertyPath = $violation->getPropertyPath();
5251
$prefix = $propertyPath ? sprintf('%s: ', $propertyPath) : '';
@@ -55,19 +54,22 @@ public function normalize($object, $format = null, array $context = [])
5554
}
5655

5756
return [
58-
'@context' => $this->urlGenerator->generate('api_jsonld_context', ['shortName' => 'ConstraintViolationList']),
59-
'@type' => 'ConstraintViolationList',
60-
'hydra:title' => $context['title'] ?? 'An error occurred',
61-
'hydra:description' => $messages ? implode("\n", $messages) : (string) $object,
62-
'violations' => $violations,
63-
];
57+
'@context' => $this->urlGenerator->generate(
58+
'api_jsonld_context',
59+
['shortName' => 'ConstraintViolationList']
60+
),
61+
'@type' => 'ConstraintViolationList',
62+
'hydra:title' => $context['title'] ?? 'An error occurred',
63+
'hydra:description' => $messages ? implode("\n", $messages) : (string) $object,
64+
'violations' => $violations,
65+
];
6466
}
6567

6668
/**
6769
* {@inheritdoc}
6870
*/
6971
public function supportsNormalization($data, $format = null)
7072
{
71-
return self::FORMAT === $format && $data instanceof ConstraintViolationListInterface;
73+
return in_array($format, self::FORMAT) && $data instanceof ConstraintViolationListInterface;
7274
}
7375
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace ApiPlatform\Core\Bridge\Symfony\Validator\Swagger\EventListener;
13+
14+
use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
15+
use ApiPlatform\Core\JsonLd\Response;
16+
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
17+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
18+
19+
/**
20+
* Handles validation errors.
21+
*
22+
* @author Kévin Dunglas <[email protected]>
23+
*/
24+
final class SwaggerValidationExceptionListener
25+
{
26+
private $normalizer;
27+
28+
public function __construct(NormalizerInterface $normalizer)
29+
{
30+
$this->normalizer = $normalizer;
31+
}
32+
33+
/**
34+
* Returns a list of violations normalized in the Hydra format.
35+
*
36+
* @param GetResponseForExceptionEvent $event
37+
*/
38+
public function onKernelException(GetResponseForExceptionEvent $event)
39+
{
40+
$exception = $event->getException();
41+
42+
if ($exception instanceof ValidationException) {
43+
$event->setResponse(new Response(
44+
$this->normalizer->normalize($exception->getConstraintViolationList(), 'swagger-error'),
45+
Response::HTTP_BAD_REQUEST
46+
));
47+
}
48+
}
49+
}

src/Hydra/ApiDocumentationBuilder.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
2222
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceNameCollectionFactoryInterface;
2323
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
24+
use ApiPlatform\Core\Util\ApiDocumentationBuilderInterface;
2425

2526
/**
2627
* Creates a machine readable Hydra API documentation.

0 commit comments

Comments
 (0)