Skip to content

Commit e09e73e

Browse files
authored
feat: remove hydra prefix (#6418)
* feat: remove hydra prefix * fix: add hydra context
1 parent 3cada4c commit e09e73e

File tree

24 files changed

+696
-147
lines changed

24 files changed

+696
-147
lines changed

features/hydra/collection.feature

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,3 +586,11 @@ Feature: Collections support
586586
}
587587
}
588588
"""
589+
590+
Scenario: Hydra collection without prefix
591+
When I send a "GET" request to "/no_hydra_prefixes"
592+
Then the response status code should be 200
593+
And the response should be in JSON
594+
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
595+
And the JSON node "totalItems" should exist
596+
And the JSON node "member" should exist

src/Hydra/JsonSchema/SchemaFactory.php

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Hydra\JsonSchema;
1515

1616
use ApiPlatform\JsonLd\ContextBuilder;
17+
use ApiPlatform\JsonLd\Serializer\HydraPrefixTrait;
1718
use ApiPlatform\JsonSchema\Schema;
1819
use ApiPlatform\JsonSchema\SchemaFactoryAwareInterface;
1920
use ApiPlatform\JsonSchema\SchemaFactoryInterface;
@@ -26,6 +27,7 @@
2627
*/
2728
final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareInterface
2829
{
30+
use HydraPrefixTrait;
2931
private const BASE_PROP = [
3032
'readOnly' => true,
3133
'type' => 'string',
@@ -57,7 +59,7 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI
5759
],
5860
] + self::BASE_PROPS;
5961

60-
public function __construct(private readonly SchemaFactoryInterface $schemaFactory)
62+
public function __construct(private readonly SchemaFactoryInterface $schemaFactory, private readonly array $defaultContext = [])
6163
{
6264
if ($this->schemaFactory instanceof SchemaFactoryAwareInterface) {
6365
$this->schemaFactory->setSchemaFactory($this);
@@ -105,17 +107,18 @@ public function buildSchema(string $className, string $format = 'jsonld', string
105107
break;
106108
}
107109

110+
$hydraPrefix = $this->getHydraPrefix(($serializerContext ?? []) + $this->defaultContext);
108111
$schema['type'] = 'object';
109112
$schema['properties'] = [
110-
'hydra:member' => [
113+
$hydraPrefix.'member' => [
111114
'type' => 'array',
112115
'items' => $items,
113116
],
114-
'hydra:totalItems' => [
117+
$hydraPrefix.'totalItems' => [
115118
'type' => 'integer',
116119
'minimum' => 0,
117120
],
118-
'hydra:view' => [
121+
$hydraPrefix.'view' => [
119122
'type' => 'object',
120123
'properties' => [
121124
'@id' => [
@@ -125,39 +128,39 @@ public function buildSchema(string $className, string $format = 'jsonld', string
125128
'@type' => [
126129
'type' => 'string',
127130
],
128-
'hydra:first' => [
131+
$hydraPrefix.'first' => [
129132
'type' => 'string',
130133
'format' => 'iri-reference',
131134
],
132-
'hydra:last' => [
135+
$hydraPrefix.'last' => [
133136
'type' => 'string',
134137
'format' => 'iri-reference',
135138
],
136-
'hydra:previous' => [
139+
$hydraPrefix.'previous' => [
137140
'type' => 'string',
138141
'format' => 'iri-reference',
139142
],
140-
'hydra:next' => [
143+
$hydraPrefix.'next' => [
141144
'type' => 'string',
142145
'format' => 'iri-reference',
143146
],
144147
],
145148
'example' => [
146149
'@id' => 'string',
147150
'type' => 'string',
148-
'hydra:first' => 'string',
149-
'hydra:last' => 'string',
150-
'hydra:previous' => 'string',
151-
'hydra:next' => 'string',
151+
$hydraPrefix.'first' => 'string',
152+
$hydraPrefix.'last' => 'string',
153+
$hydraPrefix.'previous' => 'string',
154+
$hydraPrefix.'next' => 'string',
152155
],
153156
],
154-
'hydra:search' => [
157+
$hydraPrefix.'search' => [
155158
'type' => 'object',
156159
'properties' => [
157160
'@type' => ['type' => 'string'],
158-
'hydra:template' => ['type' => 'string'],
159-
'hydra:variableRepresentation' => ['type' => 'string'],
160-
'hydra:mapping' => [
161+
$hydraPrefix.'template' => ['type' => 'string'],
162+
$hydraPrefix.'variableRepresentation' => ['type' => 'string'],
163+
$hydraPrefix.'mapping' => [
161164
'type' => 'array',
162165
'items' => [
163166
'type' => 'object',
@@ -173,7 +176,7 @@ public function buildSchema(string $className, string $format = 'jsonld', string
173176
],
174177
];
175178
$schema['required'] = [
176-
'hydra:member',
179+
$hydraPrefix.'member',
177180
];
178181

179182
return $schema;

src/Hydra/Serializer/CollectionFiltersNormalizer.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use ApiPlatform\Api\ResourceClassResolverInterface as LegacyResourceClassResolverInterface;
1717
use ApiPlatform\Doctrine\Odm\State\Options as ODMOptions;
1818
use ApiPlatform\Doctrine\Orm\State\Options;
19+
use ApiPlatform\JsonLd\Serializer\HydraPrefixTrait;
1920
use ApiPlatform\Metadata\FilterInterface;
2021
use ApiPlatform\Metadata\Parameter;
2122
use ApiPlatform\Metadata\Parameters;
@@ -38,12 +39,14 @@
3839
*/
3940
final class CollectionFiltersNormalizer implements NormalizerInterface, NormalizerAwareInterface, CacheableSupportsMethodInterface
4041
{
42+
use HydraPrefixTrait;
4143
private ?ContainerInterface $filterLocator = null;
4244

4345
/**
44-
* @param ContainerInterface $filterLocator The new filter locator or the deprecated filter collection
46+
* @param ContainerInterface $filterLocator The new filter locator or the deprecated filter collection
47+
* @param array<string, mixed> $defaultContext
4548
*/
46-
public function __construct(private readonly NormalizerInterface $collectionNormalizer, private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, private readonly LegacyResourceClassResolverInterface|ResourceClassResolverInterface $resourceClassResolver, ContainerInterface $filterLocator)
49+
public function __construct(private readonly NormalizerInterface $collectionNormalizer, private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, private readonly LegacyResourceClassResolverInterface|ResourceClassResolverInterface $resourceClassResolver, ContainerInterface $filterLocator, private readonly array $defaultContext = [])
4750
{
4851
$this->filterLocator = $filterLocator;
4952
}
@@ -128,7 +131,8 @@ public function normalize(mixed $object, ?string $format = null, array $context
128131
}
129132

130133
if ($currentFilters || ($parameters && \count($parameters))) {
131-
$data['hydra:search'] = $this->getSearch($resourceClass, $requestParts, $currentFilters, $parameters);
134+
$hydraPrefix = $this->getHydraPrefix($context + $this->defaultContext);
135+
$data[$hydraPrefix.'search'] = $this->getSearch($resourceClass, $requestParts, $currentFilters, $parameters, $hydraPrefix);
132136
}
133137

134138
return $data;
@@ -150,7 +154,7 @@ public function setNormalizer(NormalizerInterface $normalizer): void
150154
* @param FilterInterface[] $filters
151155
* @param array<string, Parameter> $parameters
152156
*/
153-
private function getSearch(string $resourceClass, array $parts, array $filters, array|Parameters|null $parameters): array
157+
private function getSearch(string $resourceClass, array $parts, array $filters, array|Parameters|null $parameters, string $hydraPrefix): array
154158
{
155159
$variables = [];
156160
$mapping = [];
@@ -200,7 +204,7 @@ private function getSearch(string $resourceClass, array $parts, array $filters,
200204
$mapping[] = $m;
201205
}
202206

203-
return ['@type' => 'hydra:IriTemplate', 'hydra:template' => \sprintf('%s{?%s}', $parts['path'], implode(',', $variables)), 'hydra:variableRepresentation' => 'BasicRepresentation', 'hydra:mapping' => $mapping];
207+
return ['@type' => $hydraPrefix.'IriTemplate', $hydraPrefix.'template' => \sprintf('%s{?%s}', $parts['path'], implode(',', $variables)), $hydraPrefix.'variableRepresentation' => 'BasicRepresentation', $hydraPrefix.'mapping' => $mapping];
204208
}
205209

206210
/**

src/Hydra/Serializer/CollectionNormalizer.php

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use ApiPlatform\Api\IriConverterInterface as LegacyIriConverterInterface;
1717
use ApiPlatform\Api\ResourceClassResolverInterface as LegacyResourceClassResolverInterface;
1818
use ApiPlatform\JsonLd\ContextBuilderInterface;
19+
use ApiPlatform\JsonLd\Serializer\HydraPrefixTrait;
1920
use ApiPlatform\JsonLd\Serializer\JsonLdContextTrait;
2021
use ApiPlatform\Metadata\IriConverterInterface;
2122
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
@@ -33,6 +34,7 @@
3334
*/
3435
final class CollectionNormalizer extends AbstractCollectionNormalizer
3536
{
37+
use HydraPrefixTrait;
3638
use JsonLdContextTrait;
3739

3840
public const FORMAT = 'jsonld';
@@ -58,18 +60,19 @@ public function __construct(private readonly ContextBuilderInterface $contextBui
5860
protected function getPaginationData(iterable $object, array $context = []): array
5961
{
6062
$resourceClass = $this->resourceClassResolver->getResourceClass($object, $context['resource_class']);
63+
$hydraPrefix = $this->getHydraPrefix($context + $this->defaultContext);
6164
// This adds "jsonld_has_context" by reference, we moved the code to this class.
6265
// To follow a note I wrote in the ItemNormalizer, we need to change the JSON-LD context generation as it is more complicated then it should.
6366
$data = $this->addJsonLdContext($this->contextBuilder, $resourceClass, $context);
6467
$data['@id'] = $this->iriConverter->getIriFromResource($resourceClass, UrlGeneratorInterface::ABS_PATH, $context['operation'] ?? null, $context);
65-
$data['@type'] = 'hydra:Collection';
68+
$data['@type'] = $hydraPrefix.'Collection';
6669

6770
if ($object instanceof PaginatorInterface) {
68-
$data['hydra:totalItems'] = $object->getTotalItems();
71+
$data[$hydraPrefix.'totalItems'] = $object->getTotalItems();
6972
}
7073

7174
if (\is_array($object) || ($object instanceof \Countable && !$object instanceof PartialPaginatorInterface)) {
72-
$data['hydra:totalItems'] = \count($object);
75+
$data[$hydraPrefix.'totalItems'] = \count($object);
7376
}
7477

7578
return $data;
@@ -80,15 +83,15 @@ protected function getPaginationData(iterable $object, array $context = []): arr
8083
*/
8184
protected function getItemsData(iterable $object, ?string $format = null, array $context = []): array
8285
{
83-
$data = [];
84-
$data['hydra:member'] = [];
86+
$hydraPrefix = $this->getHydraPrefix($context + $this->defaultContext);
87+
$data = [$hydraPrefix.'member' => []];
8588
$iriOnly = $context[self::IRI_ONLY] ?? $this->defaultContext[self::IRI_ONLY];
8689

8790
foreach ($object as $obj) {
8891
if ($iriOnly) {
89-
$data['hydra:member'][] = $this->iriConverter->getIriFromResource($obj);
92+
$data[$hydraPrefix.'member'][] = $this->iriConverter->getIriFromResource($obj);
9093
} else {
91-
$data['hydra:member'][] = $this->normalizer->normalize($obj, $format, $context + ['jsonld_has_context' => true]);
94+
$data[$hydraPrefix.'member'][] = $this->normalizer->normalize($obj, $format, $context + ['jsonld_has_context' => true]);
9295
}
9396
}
9497

src/Hydra/Serializer/ConstraintViolationListNormalizer.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Hydra\Serializer;
1515

1616
use ApiPlatform\Api\UrlGeneratorInterface as LegacyUrlGeneratorInterface;
17+
use ApiPlatform\JsonLd\Serializer\HydraPrefixTrait;
1718
use ApiPlatform\Metadata\UrlGeneratorInterface;
1819
use ApiPlatform\Serializer\AbstractConstraintViolationListNormalizer;
1920
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
@@ -25,6 +26,7 @@
2526
*/
2627
final class ConstraintViolationListNormalizer extends AbstractConstraintViolationListNormalizer
2728
{
29+
use HydraPrefixTrait;
2830
public const FORMAT = 'jsonld';
2931

3032
public function __construct(private readonly UrlGeneratorInterface|LegacyUrlGeneratorInterface $urlGenerator, ?array $serializePayloadFields = null, ?NameConverterInterface $nameConverter = null)
@@ -44,11 +46,13 @@ public function normalize(mixed $object, ?string $format = null, array $context
4446
return $violations;
4547
}
4648

49+
$hydraPrefix = $this->getHydraPrefix($context);
50+
4751
return [
4852
'@context' => $this->urlGenerator->generate('api_jsonld_context', ['shortName' => 'ConstraintViolationList']),
4953
'@type' => 'ConstraintViolationList',
50-
'hydra:title' => $context['title'] ?? 'An error occurred',
51-
'hydra:description' => $messages ? implode("\n", $messages) : (string) $object,
54+
$hydraPrefix.'title' => $context['title'] ?? 'An error occurred',
55+
$hydraPrefix.'description' => $messages ? implode("\n", $messages) : (string) $object,
5256
'violations' => $violations,
5357
];
5458
}

0 commit comments

Comments
 (0)