Skip to content

Commit e9818e1

Browse files
committed
fix(laravel): serializer default context
1 parent 7110dc6 commit e9818e1

File tree

4 files changed

+91
-42
lines changed

4 files changed

+91
-42
lines changed

src/Laravel/ApiPlatformProvider.php

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@
4444
use ApiPlatform\GraphQl\Type\TypesFactory;
4545
use ApiPlatform\GraphQl\Type\TypesFactoryInterface;
4646
use ApiPlatform\Hydra\JsonSchema\SchemaFactory as HydraSchemaFactory;
47-
use ApiPlatform\Hydra\Serializer\CollectionFiltersNormalizer as HydraFiltersCollectionNormalizer;
47+
use ApiPlatform\Hydra\Serializer\CollectionFiltersNormalizer as HydraCollectionFiltersNormalizer;
4848
use ApiPlatform\Hydra\Serializer\CollectionNormalizer as HydraCollectionNormalizer;
4949
use ApiPlatform\Hydra\Serializer\DocumentationNormalizer as HydraDocumentationNormalizer;
5050
use ApiPlatform\Hydra\Serializer\EntrypointNormalizer as HydraEntrypointNormalizer;
51+
use ApiPlatform\Hydra\Serializer\HydraPrefixNameConverter;
5152
use ApiPlatform\Hydra\Serializer\PartialCollectionViewNormalizer as HydraPartialCollectionViewNormalizer;
5253
use ApiPlatform\Hydra\State\HydraLinkProcessor;
5354
use ApiPlatform\JsonApi\JsonSchema\SchemaFactory as JsonApiSchemaFactory;
@@ -219,7 +220,6 @@ class ApiPlatformProvider extends ServiceProvider
219220
public function register(): void
220221
{
221222
$this->mergeConfigFrom(__DIR__.'/config/api-platform.php', 'api-platform');
222-
$defaultContext = [];
223223

224224
$this->app->singleton(PropertyInfoExtractorInterface::class, function () {
225225
$phpDocExtractor = class_exists(DocBlockFactory::class) ? new PhpDocExtractor() : null;
@@ -384,7 +384,10 @@ public function register(): void
384384
});
385385

386386
$this->app->bind(NameConverterInterface::class, function (Application $app) {
387-
return new MetadataAwareNameConverter($app->make(ClassMetadataFactoryInterface::class), $app->make(SnakeCaseToCamelCaseNameConverter::class));
387+
$config = $app['config'];
388+
$defaultContext = $config->get('api-platform.serializer', []);
389+
390+
return new HydraPrefixNameConverter(new MetadataAwareNameConverter($app->make(ClassMetadataFactoryInterface::class), $app->make(SnakeCaseToCamelCaseNameConverter::class)), $defaultContext);
388391
});
389392

390393
$this->app->bind(OperationMetadataFactoryInterface::class, OperationMetadataFactory::class);
@@ -528,20 +531,29 @@ public function register(): void
528531

529532
$this->app->bind(ProcessorInterface::class, HydraLinkProcessor::class);
530533

531-
$this->app->singleton(ObjectNormalizer::class, function () {
532-
return new ObjectNormalizer();
534+
$this->app->singleton(ObjectNormalizer::class, function (Application $app) {
535+
$config = $app['config'];
536+
$defaultContext = $config->get('api-platform.serializer', []);
537+
538+
return new ObjectNormalizer(defaultContext: $defaultContext);
533539
});
534540

535-
$this->app->singleton(DateTimeNormalizer::class, function () {
536-
return new DateTimeNormalizer();
541+
$this->app->singleton(DateTimeNormalizer::class, function (Application $app) {
542+
$config = $app['config'];
543+
$defaultContext = $config->get('api-platform.serializer', []);
544+
545+
return new DateTimeNormalizer(defaultContext: $defaultContext);
537546
});
538547

539548
$this->app->singleton(DateTimeZoneNormalizer::class, function () {
540549
return new DateTimeZoneNormalizer();
541550
});
542551

543-
$this->app->singleton(DateIntervalNormalizer::class, function () {
544-
return new DateIntervalNormalizer();
552+
$this->app->singleton(DateIntervalNormalizer::class, function (Application $app) {
553+
$config = $app['config'];
554+
$defaultContext = $config->get('api-platform.serializer', []);
555+
556+
return new DateIntervalNormalizer(defaultContext: $defaultContext);
545557
});
546558

547559
$this->app->singleton(JsonEncoder::class, function () {
@@ -589,14 +601,18 @@ public function register(): void
589601

590602
$this->app->bind(ContextBuilderInterface::class, JsonLdContextBuilder::class);
591603
$this->app->singleton(JsonLdContextBuilder::class, function (Application $app) {
604+
$config = $app['config'];
605+
$defaultContext = $config->get('api-platform.serializer', []);
606+
592607
return new JsonLdContextBuilder(
593608
$app->make(ResourceNameCollectionFactoryInterface::class),
594609
$app->make(ResourceMetadataCollectionFactoryInterface::class),
595610
$app->make(PropertyNameCollectionFactoryInterface::class),
596611
$app->make(PropertyMetadataFactoryInterface::class),
597612
$app->make(UrlGeneratorInterface::class),
598613
$app->make(IriConverterInterface::class),
599-
$app->make(NameConverterInterface::class)
614+
$app->make(NameConverterInterface::class),
615+
$defaultContext
600616
);
601617
});
602618

@@ -608,7 +624,11 @@ public function register(): void
608624
return new ResourceAccessChecker();
609625
});
610626

611-
$this->app->singleton(ItemNormalizer::class, function (Application $app) use ($defaultContext) {
627+
$this->app->singleton(ItemNormalizer::class, function (Application $app) {
628+
/** @var ConfigRepository */
629+
$config = $app['config'];
630+
$defaultContext = $config->get('api-platform.serializer', []);
631+
612632
return new ItemNormalizer(
613633
$app->make(PropertyNameCollectionFactoryInterface::class),
614634
$app->make(PropertyMetadataFactoryInterface::class),
@@ -733,8 +753,12 @@ public function register(): void
733753
);
734754
});
735755
$this->app->singleton(HydraSchemaFactory::class, function (Application $app) {
756+
$config = $app['config'];
757+
$defaultContext = $config->get('api-platform.serializer', []);
758+
736759
return new HydraSchemaFactory(
737760
$app->make(JsonApiSchemaFactory::class),
761+
$defaultContext
738762
);
739763
});
740764

@@ -745,19 +769,26 @@ public function register(): void
745769
});
746770

747771
$this->app->singleton(HydraDocumentationNormalizer::class, function (Application $app) {
772+
$config = $app['config'];
773+
$defaultContext = $config->get('api-platform.serializer', []);
774+
748775
return new HydraDocumentationNormalizer(
749776
$app->make(ResourceMetadataCollectionFactoryInterface::class),
750777
$app->make(PropertyNameCollectionFactoryInterface::class),
751778
$app->make(PropertyMetadataFactoryInterface::class),
752779
$app->make(ResourceClassResolverInterface::class),
753780
$app->make(UrlGeneratorInterface::class),
754-
$app->make(NameConverterInterface::class)
781+
$app->make(NameConverterInterface::class),
782+
$defaultContext
755783
);
756784
});
757785

758-
$this->app->singleton(HydraPartialCollectionViewNormalizer::class, function (Application $app) use ($defaultContext) {
786+
$this->app->singleton(HydraPartialCollectionViewNormalizer::class, function (Application $app) {
787+
$config = $app['config'];
788+
$defaultContext = $config->get('api-platform.serializer', []);
789+
759790
return new HydraPartialCollectionViewNormalizer(
760-
new HydraFiltersCollectionNormalizer(
791+
new HydraCollectionFiltersNormalizer(
761792
new HydraCollectionNormalizer(
762793
$app->make(ContextBuilderInterface::class),
763794
$app->make(ResourceClassResolverInterface::class),
@@ -767,11 +798,15 @@ public function register(): void
767798
),
768799
$app->make(ResourceMetadataCollectionFactoryInterface::class),
769800
$app->make(ResourceClassResolverInterface::class),
801+
null, // filterLocator, we use only Parameters with Laravel and we don't need to call filters there
802+
$defaultContext
770803
),
771804
'page',
772805
'pagination',
773806
$app->make(ResourceMetadataCollectionFactoryInterface::class),
774807
$app->make(PropertyAccessorInterface::class),
808+
$config->get('api-platform.url_generation_strategy', UrlGeneratorInterface::ABS_PATH),
809+
$defaultContext,
775810
);
776811
});
777812

@@ -798,7 +833,10 @@ public function register(): void
798833
);
799834
});
800835

801-
$this->app->singleton(JsonApiItemNormalizer::class, function (Application $app) use ($defaultContext) {
836+
$this->app->singleton(JsonApiItemNormalizer::class, function (Application $app) {
837+
$config = $app['config'];
838+
$defaultContext = $config->get('api-platform.serializer', []);
839+
802840
return new JsonApiItemNormalizer(
803841
$app->make(PropertyNameCollectionFactoryInterface::class),
804842
$app->make(PropertyMetadataFactoryInterface::class),
@@ -915,7 +953,10 @@ public function register(): void
915953
return new Serializer(iterator_to_array($list), [new JsonEncoder('json'), $app->make(JsonEncoder::class), new JsonEncoder('jsonopenapi'), new JsonEncoder('jsonapi')]);
916954
});
917955

918-
$this->app->singleton(JsonLdItemNormalizer::class, function (Application $app) use ($defaultContext) {
956+
$this->app->singleton(JsonLdItemNormalizer::class, function (Application $app) {
957+
$config = $app['config'];
958+
$defaultContext = $config->get('api-platform.serializer', []);
959+
919960
return new JsonLdItemNormalizer(
920961
$app->make(ResourceMetadataCollectionFactoryInterface::class),
921962
$app->make(PropertyNameCollectionFactoryInterface::class),

src/Laravel/Tests/EloquentTest.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,16 @@ class EloquentTest extends TestCase
2727
public function testSearchFilter(): void
2828
{
2929
$response = $this->get('/api/books', ['accept' => ['application/ld+json']]);
30-
$book = $response->json()['hydra:member'][0];
30+
$book = $response->json()['member'][0];
3131

3232
$response = $this->get('/api/books?isbn='.$book['isbn'], ['accept' => ['application/ld+json']]);
33-
$this->assertSame($response->json()['hydra:member'][0], $book);
33+
$this->assertSame($response->json()['member'][0], $book);
3434
}
3535

3636
public function testPartialSearchFilter(): void
3737
{
3838
$response = $this->get('/api/books', ['accept' => ['application/ld+json']]);
39-
$book = $response->json()['hydra:member'][0];
39+
$book = $response->json()['member'][0];
4040

4141
if (!isset($book['name'])) {
4242
throw new \UnexpectedValueException();
@@ -46,13 +46,13 @@ public function testPartialSearchFilter(): void
4646
$name = substr($book['name'], 0, $end);
4747

4848
$response = $this->get('/api/books?name='.$name, ['accept' => ['application/ld+json']]);
49-
$this->assertSame($response->json()['hydra:member'][0], $book);
49+
$this->assertSame($response->json()['member'][0], $book);
5050
}
5151

5252
public function testDateSearchFilter(): void
5353
{
5454
$response = $this->get('/api/books', ['accept' => ['application/ld+json']]);
55-
$book = $response->json()['hydra:member'][0];
55+
$book = $response->json()['member'][0];
5656
$updated = $this->patchJson(
5757
$book['@id'],
5858
['publicationDate' => '2024-02-18 00:00:00'],
@@ -63,34 +63,34 @@ public function testDateSearchFilter(): void
6363
);
6464

6565
$response = $this->get('/api/books?publicationDate='.$updated['publicationDate'], ['accept' => ['application/ld+json']]);
66-
$this->assertSame($response->json()['hydra:member'][0]['@id'], $book['@id']);
66+
$this->assertSame($response->json()['member'][0]['@id'], $book['@id']);
6767
}
6868

6969
public function testSearchFilterWithPropertyPlaceholder(): void
7070
{
7171
$response = $this->get('/api/authors', ['accept' => ['application/ld+json']])->json();
72-
$author = $response['hydra:member'][0];
72+
$author = $response['member'][0];
7373

7474
$test = $this->get('/api/authors?name='.explode(' ', $author['name'])[0], ['accept' => ['application/ld+json']])->json();
75-
$this->assertSame($test['hydra:member'][0]['id'], $author['id']);
75+
$this->assertSame($test['member'][0]['id'], $author['id']);
7676

7777
$test = $this->get('/api/authors?id='.$author['id'], ['accept' => ['application/ld+json']])->json();
78-
$this->assertSame($test['hydra:member'][0]['id'], $author['id']);
78+
$this->assertSame($test['member'][0]['id'], $author['id']);
7979
}
8080

8181
public function testOrderFilterWithPropertyPlaceholder(): void
8282
{
8383
$res = $this->get('/api/authors?order[id]=desc', ['accept' => ['application/ld+json']]);
84-
$this->assertSame($res['hydra:member'][0]['id'], 10);
84+
$this->assertSame($res['member'][0]['id'], 10);
8585
}
8686

8787
public function testOrFilter(): void
8888
{
89-
$response = $this->get('/api/books', ['accept' => ['application/ld+json']])->json()['hydra:member'];
89+
$response = $this->get('/api/books', ['accept' => ['application/ld+json']])->json()['member'];
9090
$book = $response[0];
9191
$book2 = $response[1];
9292

9393
$res = $this->get(\sprintf('/api/books?name2[]=%s&name2[]=%s', $book['name'], $book2['name']), ['accept' => ['application/ld+json']])->json();
94-
$this->assertSame($res['hydra:totalItems'], 2);
94+
$this->assertSame($res['totalItems'], 2);
9595
}
9696
}

src/Laravel/Tests/JsonLdTest.php

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ public function testGetCollection(): void
3434
$response->assertJsonFragment([
3535
'@context' => '/api/contexts/Book',
3636
'@id' => '/api/books',
37-
'@type' => 'hydra:Collection',
38-
'hydra:totalItems' => 10,
37+
'@type' => 'Collection',
38+
'totalItems' => 10,
3939
]);
40-
$response->assertJsonCount(5, 'hydra:member');
40+
$response->assertJsonCount(5, 'member');
4141
}
4242

4343
public function testGetBook(): void
@@ -177,22 +177,22 @@ public function testSubresourceCollection(): void
177177
$response->assertJsonFragment([
178178
'@context' => '/api/contexts/Post',
179179
'@id' => '/api/posts',
180-
'@type' => 'hydra:Collection',
181-
'hydra:totalItems' => 10,
180+
'@type' => 'Collection',
181+
'totalItems' => 10,
182182
]);
183-
$response->assertJsonCount(10, 'hydra:member');
184-
$postIri = $response->json('hydra:member.0.@id');
185-
$commentsIri = $response->json('hydra:member.0.comments');
183+
$response->assertJsonCount(10, 'member');
184+
$postIri = $response->json('member.0.@id');
185+
$commentsIri = $response->json('member.0.comments');
186186
$this->assertMatchesRegularExpression('~^/api/posts/\d+/comments$~', $commentsIri);
187187
$response = $this->get($commentsIri, ['accept' => 'application/ld+json']);
188188
$response->assertJsonFragment([
189189
'@context' => '/api/contexts/Comment',
190190
'@id' => $commentsIri,
191-
'@type' => 'hydra:Collection',
192-
'hydra:totalItems' => 10,
191+
'@type' => 'Collection',
192+
'totalItems' => 10,
193193
]);
194194

195-
$commentIri = $response->json('hydra:member.0.@id');
195+
$commentIri = $response->json('member.0.@id');
196196
$response = $this->get($commentIri, ['accept' => 'application/ld+json']);
197197
$response->assertJsonFragment([
198198
'@id' => $commentIri,
@@ -262,10 +262,10 @@ public function testSluggable(): void
262262
$response->assertJsonFragment([
263263
'@context' => '/api/contexts/Sluggable',
264264
'@id' => '/api/sluggables',
265-
'@type' => 'hydra:Collection',
266-
'hydra:totalItems' => 10,
265+
'@type' => 'Collection',
266+
'totalItems' => 10,
267267
]);
268-
$iri = $response->json('hydra:member.0.@id');
268+
$iri = $response->json('member.0.@id');
269269
$response = $this->get($iri, ['accept' => 'application/ld+json']);
270270
$response->assertStatus(200);
271271
}

src/Laravel/config/api-platform.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
use ApiPlatform\Metadata\UrlGeneratorInterface;
34
use Illuminate\Auth\Access\AuthorizationException;
45
use Illuminate\Auth\AuthenticationException;
56

@@ -73,5 +74,12 @@
7374

7475
'swagger_ui' => [
7576
'enabled' => true
77+
],
78+
79+
'url_generation_strategy' => UrlGeneratorInterface::ABS_PATH,
80+
81+
'serializer' => [
82+
'hydra_prefix' => false,
83+
// 'datetime_format' => \DateTimeInterface::RFC3339
7684
]
7785
];

0 commit comments

Comments
 (0)