Skip to content

Commit 066d444

Browse files
committed
Makes url generation strategy default value configurable
1 parent 44a686c commit 066d444

21 files changed

+86
-40
lines changed

src/Api/UrlGeneratorInterface.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
*/
3232
interface UrlGeneratorInterface
3333
{
34+
/**
35+
* Allow to generate url using the globally configured strategy.
36+
*/
37+
public const DEFAULT = null;
38+
3439
/**
3540
* Generates an absolute URL, e.g. "http://example.com/dir/file".
3641
*/

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ private function handleConfig(ContainerBuilder $container, array $config, array
173173
$container->setParameter('api_platform.description', $config['description']);
174174
$container->setParameter('api_platform.version', $config['version']);
175175
$container->setParameter('api_platform.show_webby', $config['show_webby']);
176+
$container->setParameter('api_platform.url_generation_strategy', $config['url_generation_strategy']);
176177
$container->setParameter('api_platform.exception_to_status', $config['exception_to_status']);
177178
$container->setParameter('api_platform.formats', $formats);
178179
$container->setParameter('api_platform.error_formats', $errorFormats);

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace ApiPlatform\Core\Bridge\Symfony\Bundle\DependencyInjection;
1515

16+
use ApiPlatform\Core\Api\UrlGeneratorInterface;
1617
use ApiPlatform\Core\Bridge\Elasticsearch\Metadata\Document\DocumentMetadata;
1718
use ApiPlatform\Core\Exception\FilterValidationException;
1819
use ApiPlatform\Core\Exception\InvalidArgumentException;
@@ -250,7 +251,10 @@ public function getConfigTreeBuilder()
250251
->arrayNode('messenger')
251252
->{interface_exists(MessageBusInterface::class) ? 'canBeDisabled' : 'canBeEnabled'}()
252253
->end()
253-
254+
->integerNode('url_generation_strategy')
255+
->defaultValue(UrlGeneratorInterface::ABS_PATH)
256+
->info('The default URL generation strategy')
257+
->end()
254258
->arrayNode('elasticsearch')
255259
->canBeEnabled()
256260
->addDefaultsIfNotSet()

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
<argument type="service" id="api_platform.identifiers_extractor.cached" />
6262
<argument type="service" id="api_platform.subresource_data_provider" on-invalid="ignore" />
6363
<argument type="service" id="api_platform.identifier.converter" on-invalid="ignore" />
64+
<argument>%api_platform.url_generation_strategy%</argument>
6465
</service>
6566
<service id="ApiPlatform\Core\Api\IriConverterInterface" alias="api_platform.iri_converter" />
6667

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
1616
<argument type="service" id="api_platform.iri_converter" />
1717
<argument type="service" id="api_platform.router" />
18+
<argument>%api_platform.url_generation_strategy%</argument>
1819

1920
<tag name="serializer.normalizer" priority="-800" />
2021
</service>

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<argument type="service" id="api_platform.router" />
1515
<argument type="service" id="api_platform.subresource_operation_factory" />
1616
<argument type="service" id="api_platform.name_converter" on-invalid="ignore" />
17+
<argument>%api_platform.url_generation_strategy%</argument>
1718

1819
<tag name="serializer.normalizer" priority="-800" />
1920
</service>
@@ -33,6 +34,7 @@
3334
<argument type="service" id="api_platform.router" />
3435
<argument>%api_platform.validator.serialize_payload_fields%</argument>
3536
<argument type="service" id="api_platform.name_converter" on-invalid="ignore" />
37+
<argument>%api_platform.url_generation_strategy%</argument>
3638

3739
<tag name="serializer.normalizer" priority="-780" />
3840
</service>
@@ -48,6 +50,8 @@
4850
<service id="api_platform.hydra.normalizer.error" class="ApiPlatform\Core\Hydra\Serializer\ErrorNormalizer" public="false">
4951
<argument type="service" id="api_platform.router" />
5052
<argument>%kernel.debug%</argument>
53+
<argument type="collection" />
54+
<argument>%api_platform.url_generation_strategy%</argument>
5155

5256
<tag name="serializer.normalizer" priority="-800" />
5357
</service>

src/Bridge/Symfony/Routing/IriConverter.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,17 @@ final class IriConverter implements IriConverterInterface
4848
private $routeNameResolver;
4949
private $router;
5050
private $identifiersExtractor;
51+
private $urlGenerationStrategy;
5152

52-
public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ItemDataProviderInterface $itemDataProvider, RouteNameResolverInterface $routeNameResolver, RouterInterface $router, PropertyAccessorInterface $propertyAccessor = null, IdentifiersExtractorInterface $identifiersExtractor = null, SubresourceDataProviderInterface $subresourceDataProvider = null, IdentifierConverterInterface $identifierConverter = null)
53+
public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ItemDataProviderInterface $itemDataProvider, RouteNameResolverInterface $routeNameResolver, RouterInterface $router, PropertyAccessorInterface $propertyAccessor = null, IdentifiersExtractorInterface $identifiersExtractor = null, SubresourceDataProviderInterface $subresourceDataProvider = null, IdentifierConverterInterface $identifierConverter = null, int $urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH)
5354
{
5455
$this->itemDataProvider = $itemDataProvider;
5556
$this->routeNameResolver = $routeNameResolver;
5657
$this->router = $router;
5758
$this->identifiersExtractor = $identifiersExtractor;
5859
$this->subresourceDataProvider = $subresourceDataProvider;
5960
$this->identifierConverter = $identifierConverter;
61+
$this->urlGenerationStrategy = $urlGenerationStrategy;
6062

6163
if (null === $identifiersExtractor) {
6264
@trigger_error(sprintf('Not injecting "%s" is deprecated since API Platform 2.1 and will not be possible anymore in API Platform 3', IdentifiersExtractorInterface::class), E_USER_DEPRECATED);
@@ -113,7 +115,7 @@ public function getItemFromIri(string $iri, array $context = [])
113115
/**
114116
* {@inheritdoc}
115117
*/
116-
public function getIriFromItem($item, int $referenceType = UrlGeneratorInterface::ABS_PATH): string
118+
public function getIriFromItem($item, int $referenceType = UrlGeneratorInterface::DEFAULT): string
117119
{
118120
$resourceClass = $this->getObjectClass($item);
119121

@@ -126,16 +128,16 @@ public function getIriFromItem($item, int $referenceType = UrlGeneratorInterface
126128
), $e->getCode(), $e);
127129
}
128130

129-
return $this->getItemIriFromResourceClass($resourceClass, $identifiers, $referenceType);
131+
return $this->getItemIriFromResourceClass($resourceClass, $identifiers, UrlGeneratorInterface::DEFAULT === $referenceType ? $this->urlGenerationStrategy : $referenceType);
130132
}
131133

132134
/**
133135
* {@inheritdoc}
134136
*/
135-
public function getIriFromResourceClass(string $resourceClass, int $referenceType = UrlGeneratorInterface::ABS_PATH): string
137+
public function getIriFromResourceClass(string $resourceClass, int $referenceType = UrlGeneratorInterface::DEFAULT): string
136138
{
137139
try {
138-
return $this->router->generate($this->routeNameResolver->getRouteName($resourceClass, OperationType::COLLECTION), [], $referenceType);
140+
return $this->router->generate($this->routeNameResolver->getRouteName($resourceClass, OperationType::COLLECTION), [], UrlGeneratorInterface::DEFAULT === $referenceType ? $this->urlGenerationStrategy : $referenceType);
139141
} catch (RoutingExceptionInterface $e) {
140142
throw new InvalidArgumentException(sprintf('Unable to generate an IRI for "%s".', $resourceClass), $e->getCode(), $e);
141143
}
@@ -144,14 +146,14 @@ public function getIriFromResourceClass(string $resourceClass, int $referenceTyp
144146
/**
145147
* {@inheritdoc}
146148
*/
147-
public function getItemIriFromResourceClass(string $resourceClass, array $identifiers, int $referenceType = UrlGeneratorInterface::ABS_PATH): string
149+
public function getItemIriFromResourceClass(string $resourceClass, array $identifiers, int $referenceType = UrlGeneratorInterface::DEFAULT): string
148150
{
149151
$routeName = $this->routeNameResolver->getRouteName($resourceClass, OperationType::ITEM);
150152

151153
try {
152154
$identifiers = $this->generateIdentifiersUrl($identifiers, $resourceClass);
153155

154-
return $this->router->generate($routeName, ['id' => implode(';', $identifiers)], $referenceType);
156+
return $this->router->generate($routeName, ['id' => implode(';', $identifiers)], UrlGeneratorInterface::DEFAULT === $referenceType ? $this->urlGenerationStrategy : $referenceType);
155157
} catch (RoutingExceptionInterface $e) {
156158
throw new InvalidArgumentException(sprintf(
157159
'Unable to generate an IRI for "%s".',
@@ -163,10 +165,10 @@ public function getItemIriFromResourceClass(string $resourceClass, array $identi
163165
/**
164166
* {@inheritdoc}
165167
*/
166-
public function getSubresourceIriFromResourceClass(string $resourceClass, array $context, int $referenceType = UrlGeneratorInterface::ABS_PATH): string
168+
public function getSubresourceIriFromResourceClass(string $resourceClass, array $context, int $referenceType = UrlGeneratorInterface::DEFAULT): string
167169
{
168170
try {
169-
return $this->router->generate($this->routeNameResolver->getRouteName($resourceClass, OperationType::SUBRESOURCE, $context), $context['subresource_identifiers'], $referenceType);
171+
return $this->router->generate($this->routeNameResolver->getRouteName($resourceClass, OperationType::SUBRESOURCE, $context), $context['subresource_identifiers'], UrlGeneratorInterface::DEFAULT === $referenceType ? $this->urlGenerationStrategy : $referenceType);
170172
} catch (RoutingExceptionInterface $e) {
171173
throw new InvalidArgumentException(sprintf('Unable to generate an IRI for "%s".', $resourceClass), $e->getCode(), $e);
172174
}

src/Hal/Serializer/EntrypointNormalizer.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,22 @@ final class EntrypointNormalizer implements NormalizerInterface, CacheableSuppor
3333
private $resourceMetadataFactory;
3434
private $iriConverter;
3535
private $urlGenerator;
36+
private $urlGenerationStrategy;
3637

37-
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, IriConverterInterface $iriConverter, UrlGeneratorInterface $urlGenerator)
38+
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, IriConverterInterface $iriConverter, UrlGeneratorInterface $urlGenerator, int $urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH)
3839
{
3940
$this->resourceMetadataFactory = $resourceMetadataFactory;
4041
$this->iriConverter = $iriConverter;
4142
$this->urlGenerator = $urlGenerator;
43+
$this->urlGenerationStrategy = $urlGenerationStrategy;
4244
}
4345

4446
/**
4547
* {@inheritdoc}
4648
*/
4749
public function normalize($object, $format = null, array $context = [])
4850
{
49-
$entrypoint = ['_links' => ['self' => ['href' => $this->urlGenerator->generate('api_entrypoint')]]];
51+
$entrypoint = ['_links' => ['self' => ['href' => $this->urlGenerator->generate('api_entrypoint', [], $this->urlGenerationStrategy)]]];
5052

5153
foreach ($object->getResourceNameCollection() as $resourceClass) {
5254
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);

src/Hydra/Serializer/ConstraintViolationListNormalizer.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@ final class ConstraintViolationListNormalizer extends AbstractConstraintViolatio
2727
public const FORMAT = 'jsonld';
2828

2929
private $urlGenerator;
30+
private $urlGenerationStrategy;
3031

31-
public function __construct(UrlGeneratorInterface $urlGenerator, array $serializePayloadFields = null, NameConverterInterface $nameConverter = null)
32+
public function __construct(UrlGeneratorInterface $urlGenerator, array $serializePayloadFields = null, NameConverterInterface $nameConverter = null, int $urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH)
3233
{
3334
parent::__construct($serializePayloadFields, $nameConverter);
3435

3536
$this->urlGenerator = $urlGenerator;
37+
$this->urlGenerationStrategy = $urlGenerationStrategy;
3638
}
3739

3840
/**
@@ -43,7 +45,7 @@ public function normalize($object, $format = null, array $context = [])
4345
[$messages, $violations] = $this->getMessagesAndViolations($object);
4446

4547
return [
46-
'@context' => $this->urlGenerator->generate('api_jsonld_context', ['shortName' => 'ConstraintViolationList']),
48+
'@context' => $this->urlGenerator->generate('api_jsonld_context', ['shortName' => 'ConstraintViolationList'], $this->urlGenerationStrategy),
4749
'@type' => 'ConstraintViolationList',
4850
'hydra:title' => $context['title'] ?? 'An error occurred',
4951
'hydra:description' => $messages ? implode("\n", $messages) : (string) $object,

src/Hydra/Serializer/DocumentationNormalizer.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ final class DocumentationNormalizer implements NormalizerInterface, CacheableSup
4949
private $urlGenerator;
5050
private $subresourceOperationFactory;
5151
private $nameConverter;
52+
private $urlGenerationStrategy;
5253

53-
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, OperationMethodResolverInterface $operationMethodResolver, UrlGeneratorInterface $urlGenerator, SubresourceOperationFactoryInterface $subresourceOperationFactory = null, NameConverterInterface $nameConverter = null)
54+
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, OperationMethodResolverInterface $operationMethodResolver, UrlGeneratorInterface $urlGenerator, SubresourceOperationFactoryInterface $subresourceOperationFactory = null, NameConverterInterface $nameConverter = null, int $urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH)
5455
{
5556
$this->resourceMetadataFactory = $resourceMetadataFactory;
5657
$this->propertyNameCollectionFactory = $propertyNameCollectionFactory;
@@ -60,6 +61,7 @@ public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFa
6061
$this->urlGenerator = $urlGenerator;
6162
$this->subresourceOperationFactory = $subresourceOperationFactory;
6263
$this->nameConverter = $nameConverter;
64+
$this->urlGenerationStrategy = $urlGenerationStrategy;
6365
}
6466

6567
/**
@@ -499,7 +501,7 @@ private function getProperty(PropertyMetadata $propertyMetadata, string $propert
499501
*/
500502
private function computeDoc(Documentation $object, array $classes): array
501503
{
502-
$doc = ['@context' => $this->getContext(), '@id' => $this->urlGenerator->generate('api_doc', ['_format' => self::FORMAT]), '@type' => 'hydra:ApiDocumentation'];
504+
$doc = ['@context' => $this->getContext(), '@id' => $this->urlGenerator->generate('api_doc', ['_format' => self::FORMAT], $this->urlGenerationStrategy), '@type' => 'hydra:ApiDocumentation'];
503505

504506
if ('' !== $object->getTitle()) {
505507
$doc['hydra:title'] = $object->getTitle();
@@ -509,7 +511,7 @@ private function computeDoc(Documentation $object, array $classes): array
509511
$doc['hydra:description'] = $object->getDescription();
510512
}
511513

512-
$doc['hydra:entrypoint'] = $this->urlGenerator->generate('api_entrypoint');
514+
$doc['hydra:entrypoint'] = $this->urlGenerator->generate('api_entrypoint', [], $this->urlGenerationStrategy);
513515
$doc['hydra:supportedClass'] = $classes;
514516

515517
return $doc;

src/Hydra/Serializer/EntrypointNormalizer.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ final class EntrypointNormalizer implements NormalizerInterface, CacheableSuppor
3333
private $resourceMetadataFactory;
3434
private $iriConverter;
3535
private $urlGenerator;
36+
private $urlGenerationStrategy;
3637

37-
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, IriConverterInterface $iriConverter, UrlGeneratorInterface $urlGenerator)
38+
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, IriConverterInterface $iriConverter, UrlGeneratorInterface $urlGenerator, int $urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH)
3839
{
3940
$this->resourceMetadataFactory = $resourceMetadataFactory;
4041
$this->iriConverter = $iriConverter;
4142
$this->urlGenerator = $urlGenerator;
43+
$this->urlGenerationStrategy = $urlGenerationStrategy;
4244
}
4345

4446
/**
@@ -47,8 +49,8 @@ public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFa
4749
public function normalize($object, $format = null, array $context = [])
4850
{
4951
$entrypoint = [
50-
'@context' => $this->urlGenerator->generate('api_jsonld_context', ['shortName' => 'Entrypoint']),
51-
'@id' => $this->urlGenerator->generate('api_entrypoint'),
52+
'@context' => $this->urlGenerator->generate('api_jsonld_context', ['shortName' => 'Entrypoint'], $this->urlGenerationStrategy),
53+
'@id' => $this->urlGenerator->generate('api_entrypoint', [], $this->urlGenerationStrategy),
5254
'@type' => 'Entrypoint',
5355
];
5456

src/Hydra/Serializer/ErrorNormalizer.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ final class ErrorNormalizer implements NormalizerInterface, CacheableSupportsMet
3535
private $urlGenerator;
3636
private $debug;
3737
private $defaultContext = [self::TITLE => 'An error occurred'];
38+
private $urlGenerationStrategy;
3839

39-
public function __construct(UrlGeneratorInterface $urlGenerator, bool $debug = false, array $defaultContext = [])
40+
public function __construct(UrlGeneratorInterface $urlGenerator, bool $debug = false, array $defaultContext = [], int $urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH)
4041
{
4142
$this->urlGenerator = $urlGenerator;
4243
$this->debug = $debug;
4344
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
45+
$this->urlGenerationStrategy = $urlGenerationStrategy;
4446
}
4547

4648
/**
@@ -49,7 +51,7 @@ public function __construct(UrlGeneratorInterface $urlGenerator, bool $debug = f
4951
public function normalize($object, $format = null, array $context = [])
5052
{
5153
$data = [
52-
'@context' => $this->urlGenerator->generate('api_jsonld_context', ['shortName' => 'Error']),
54+
'@context' => $this->urlGenerator->generate('api_jsonld_context', ['shortName' => 'Error'], $this->urlGenerationStrategy),
5355
'@type' => 'hydra:Error',
5456
'hydra:title' => $context[self::TITLE] ?? $this->defaultContext[self::TITLE],
5557
'hydra:description' => $this->getErrorMessage($object, $context, $this->debug),

0 commit comments

Comments
 (0)