Skip to content

Commit 891b950

Browse files
committed
feat(serializer): remove pagination attributes when explicitly disabled
1 parent 44f2271 commit 891b950

File tree

5 files changed

+523
-119
lines changed

5 files changed

+523
-119
lines changed

src/Hal/JsonSchema/SchemaFactory.php

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI
3535
use SchemaUriPrefixTrait;
3636

3737
private const COLLECTION_BASE_SCHEMA_NAME = 'HalCollectionBaseSchema';
38+
private const COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION = 'HalCollectionBaseSchemaNoPagination';
3839

3940
private const HREF_PROP = [
4041
'href' => [
@@ -122,10 +123,14 @@ public function buildSchema(string $className, string $format = 'jsonhal', strin
122123
}
123124

124125
if (($schema['type'] ?? '') === 'array') {
125-
if (!isset($definitions[self::COLLECTION_BASE_SCHEMA_NAME])) {
126-
$definitions[self::COLLECTION_BASE_SCHEMA_NAME] = [
126+
if (!isset($definitions[self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION])) {
127+
$definitions[self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION] = [
127128
'type' => 'object',
128129
'properties' => [
130+
'totalItems' => [
131+
'type' => 'integer',
132+
'minimum' => 0,
133+
],
129134
'_embedded' => [
130135
'anyOf' => [
131136
[
@@ -139,41 +144,52 @@ public function buildSchema(string $className, string $format = 'jsonhal', strin
139144
['type' => 'object'],
140145
],
141146
],
142-
'totalItems' => [
143-
'type' => 'integer',
144-
'minimum' => 0,
145-
],
146-
'itemsPerPage' => [
147-
'type' => 'integer',
148-
'minimum' => 0,
149-
],
150147
'_links' => [
151148
'type' => 'object',
152149
'properties' => [
153150
'self' => [
154151
'type' => 'object',
155152
'properties' => self::HREF_PROP,
156153
],
157-
'first' => [
158-
'type' => 'object',
159-
'properties' => self::HREF_PROP,
160-
],
161-
'last' => [
162-
'type' => 'object',
163-
'properties' => self::HREF_PROP,
164-
],
165-
'next' => [
166-
'type' => 'object',
167-
'properties' => self::HREF_PROP,
154+
],
155+
],
156+
],
157+
'required' => ['_links', '_embedded'],
158+
];
159+
160+
$definitions[self::COLLECTION_BASE_SCHEMA_NAME] = [
161+
'allOf' => [
162+
['$ref' => $prefix.self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION],
163+
[
164+
'type' => 'object',
165+
'properties' => [
166+
'itemsPerPage' => [
167+
'type' => 'integer',
168+
'minimum' => 0,
168169
],
169-
'previous' => [
170-
'type' => 'object',
171-
'properties' => self::HREF_PROP,
170+
'_links' => [
171+
'properties' => [
172+
'first' => [
173+
'type' => 'object',
174+
'properties' => self::HREF_PROP,
175+
],
176+
'last' => [
177+
'type' => 'object',
178+
'properties' => self::HREF_PROP,
179+
],
180+
'next' => [
181+
'type' => 'object',
182+
'properties' => self::HREF_PROP,
183+
],
184+
'previous' => [
185+
'type' => 'object',
186+
'properties' => self::HREF_PROP,
187+
],
188+
],
172189
],
173190
],
174191
],
175192
],
176-
'required' => ['_links', '_embedded'],
177193
];
178194
}
179195

@@ -182,7 +198,7 @@ public function buildSchema(string $className, string $format = 'jsonhal', strin
182198

183199
$schema['description'] = "$definitionName collection.";
184200
$schema['allOf'] = [
185-
['$ref' => $prefix.self::COLLECTION_BASE_SCHEMA_NAME],
201+
['$ref' => $prefix.(false === $operation->getPaginationEnabled() ? self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION : self::COLLECTION_BASE_SCHEMA_NAME)],
186202
[
187203
'type' => 'object',
188204
'properties' => [

src/Hydra/JsonSchema/SchemaFactory.php

Lines changed: 51 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI
3838

3939
private const ITEM_BASE_SCHEMA_NAME = 'HydraItemBaseSchema';
4040
private const ITEM_WITHOUT_ID_BASE_SCHEMA_NAME = 'HydraItemBaseSchemaWithoutId';
41+
private const COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION = 'HydraCollectionBaseSchemaNoPagination';
4142
private const COLLECTION_BASE_SCHEMA_NAME = 'HydraCollectionBaseSchema';
4243

4344
private const BASE_PROP = [
@@ -155,7 +156,7 @@ public function buildSchema(string $className, string $format = 'jsonld', string
155156

156157
$hydraPrefix = $this->getHydraPrefix($serializerContext + $this->defaultContext);
157158

158-
if (!isset($definitions[self::COLLECTION_BASE_SCHEMA_NAME])) {
159+
if (!isset($definitions[self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION])) {
159160
switch ($schema->getVersion()) {
160161
// JSON Schema + OpenAPI 3.1
161162
case Schema::VERSION_OPENAPI:
@@ -168,49 +169,13 @@ public function buildSchema(string $className, string $format = 'jsonld', string
168169
break;
169170
}
170171

171-
$definitions[self::COLLECTION_BASE_SCHEMA_NAME] = [
172+
$definitions[self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION] = [
172173
'type' => 'object',
173174
'properties' => [
174175
$hydraPrefix.'totalItems' => [
175176
'type' => 'integer',
176177
'minimum' => 0,
177178
],
178-
$hydraPrefix.'view' => [
179-
'type' => 'object',
180-
'properties' => [
181-
'@id' => [
182-
'type' => 'string',
183-
'format' => 'iri-reference',
184-
],
185-
'@type' => [
186-
'type' => 'string',
187-
],
188-
$hydraPrefix.'first' => [
189-
'type' => 'string',
190-
'format' => 'iri-reference',
191-
],
192-
$hydraPrefix.'last' => [
193-
'type' => 'string',
194-
'format' => 'iri-reference',
195-
],
196-
$hydraPrefix.'previous' => [
197-
'type' => 'string',
198-
'format' => 'iri-reference',
199-
],
200-
$hydraPrefix.'next' => [
201-
'type' => 'string',
202-
'format' => 'iri-reference',
203-
],
204-
],
205-
'example' => [
206-
'@id' => 'string',
207-
'type' => 'string',
208-
$hydraPrefix.'first' => 'string',
209-
$hydraPrefix.'last' => 'string',
210-
$hydraPrefix.'previous' => 'string',
211-
$hydraPrefix.'next' => 'string',
212-
],
213-
],
214179
$hydraPrefix.'search' => [
215180
'type' => 'object',
216181
'properties' => [
@@ -233,13 +198,60 @@ public function buildSchema(string $className, string $format = 'jsonld', string
233198
],
234199
],
235200
];
201+
202+
$definitions[self::COLLECTION_BASE_SCHEMA_NAME] = [
203+
'allOf' => [
204+
['$ref' => $prefix.self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION],
205+
[
206+
'type' => 'object',
207+
'properties' => [
208+
$hydraPrefix.'view' => [
209+
'type' => 'object',
210+
'properties' => [
211+
'@id' => [
212+
'type' => 'string',
213+
'format' => 'iri-reference',
214+
],
215+
'@type' => [
216+
'type' => 'string',
217+
],
218+
$hydraPrefix.'first' => [
219+
'type' => 'string',
220+
'format' => 'iri-reference',
221+
],
222+
$hydraPrefix.'last' => [
223+
'type' => 'string',
224+
'format' => 'iri-reference',
225+
],
226+
$hydraPrefix.'previous' => [
227+
'type' => 'string',
228+
'format' => 'iri-reference',
229+
],
230+
$hydraPrefix.'next' => [
231+
'type' => 'string',
232+
'format' => 'iri-reference',
233+
],
234+
],
235+
'example' => [
236+
'@id' => 'string',
237+
'type' => 'string',
238+
$hydraPrefix.'first' => 'string',
239+
$hydraPrefix.'last' => 'string',
240+
$hydraPrefix.'previous' => 'string',
241+
$hydraPrefix.'next' => 'string',
242+
],
243+
],
244+
],
245+
],
246+
],
247+
];
236248
}
237249

238250
$definitionName = $this->definitionNameFactory->create($className, $format, $inputOrOutputClass, $operation, $serializerContext);
239251
$schema['type'] = 'object';
240252
$schema['description'] = "$definitionName collection.";
241253
$schema['allOf'] = [
242-
['$ref' => $prefix.self::COLLECTION_BASE_SCHEMA_NAME],
254+
['$ref' => $prefix.(false === $operation->getPaginationEnabled() ? self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION : self::COLLECTION_BASE_SCHEMA_NAME)],
243255
[
244256
'type' => 'object',
245257
'required' => [

src/JsonApi/JsonSchema/SchemaFactory.php

Lines changed: 76 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -49,56 +49,8 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI
4949
public const DISABLE_JSON_SCHEMA_SERIALIZER_GROUPS = 'disable_json_schema_serializer_groups';
5050

5151
private const COLLECTION_BASE_SCHEMA_NAME = 'JsonApiCollectionBaseSchema';
52+
private const COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION = 'JsonApiCollectionBaseSchemaNoPagination';
5253

53-
private const LINKS_PROPS = [
54-
'type' => 'object',
55-
'properties' => [
56-
'self' => [
57-
'type' => 'string',
58-
'format' => 'iri-reference',
59-
],
60-
'first' => [
61-
'type' => 'string',
62-
'format' => 'iri-reference',
63-
],
64-
'prev' => [
65-
'type' => 'string',
66-
'format' => 'iri-reference',
67-
],
68-
'next' => [
69-
'type' => 'string',
70-
'format' => 'iri-reference',
71-
],
72-
'last' => [
73-
'type' => 'string',
74-
'format' => 'iri-reference',
75-
],
76-
],
77-
'example' => [
78-
'self' => 'string',
79-
'first' => 'string',
80-
'prev' => 'string',
81-
'next' => 'string',
82-
'last' => 'string',
83-
],
84-
];
85-
private const META_PROPS = [
86-
'type' => 'object',
87-
'properties' => [
88-
'totalItems' => [
89-
'type' => 'integer',
90-
'minimum' => 0,
91-
],
92-
'itemsPerPage' => [
93-
'type' => 'integer',
94-
'minimum' => 0,
95-
],
96-
'currentPage' => [
97-
'type' => 'integer',
98-
'minimum' => 0,
99-
],
100-
],
101-
];
10254
private const RELATION_PROPS = [
10355
'type' => 'object',
10456
'properties' => [
@@ -217,18 +169,88 @@ public function buildSchema(string $className, string $format = 'jsonapi', strin
217169
return $schema;
218170
}
219171

220-
if (!isset($definitions[self::COLLECTION_BASE_SCHEMA_NAME])) {
221-
$definitions[self::COLLECTION_BASE_SCHEMA_NAME] = [
172+
if (!isset($definitions[self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION])) {
173+
$definitions[self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION] = [
222174
'type' => 'object',
223175
'properties' => [
224-
'links' => self::LINKS_PROPS,
225-
'meta' => self::META_PROPS,
176+
'links' => [
177+
'type' => 'object',
178+
'properties' => [
179+
'self' => [
180+
'type' => 'string',
181+
'format' => 'iri-reference',
182+
],
183+
],
184+
'example' => [
185+
'self' => 'string',
186+
],
187+
],
188+
'meta' => [
189+
'type' => 'object',
190+
'properties' => [
191+
'totalItems' => [
192+
'type' => 'integer',
193+
'minimum' => 0,
194+
],
195+
],
196+
],
226197
'data' => [
227198
'type' => 'array',
228199
],
229200
],
230201
'required' => ['data'],
231202
];
203+
204+
$definitions[self::COLLECTION_BASE_SCHEMA_NAME] = [
205+
'allOf' => [
206+
['$ref' => $prefix.self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION],
207+
[
208+
'type' => 'object',
209+
'properties' => [
210+
'links' => [
211+
'type' => 'object',
212+
'properties' => [
213+
'first' => [
214+
'type' => 'string',
215+
'format' => 'iri-reference',
216+
],
217+
'prev' => [
218+
'type' => 'string',
219+
'format' => 'iri-reference',
220+
],
221+
'next' => [
222+
'type' => 'string',
223+
'format' => 'iri-reference',
224+
],
225+
'last' => [
226+
'type' => 'string',
227+
'format' => 'iri-reference',
228+
],
229+
],
230+
'example' => [
231+
'first' => 'string',
232+
'prev' => 'string',
233+
'next' => 'string',
234+
'last' => 'string',
235+
],
236+
],
237+
'meta' => [
238+
'type' => 'object',
239+
'properties' => [
240+
'itemsPerPage' => [
241+
'type' => 'integer',
242+
'minimum' => 0,
243+
],
244+
'currentPage' => [
245+
'type' => 'integer',
246+
'minimum' => 0,
247+
],
248+
],
249+
],
250+
],
251+
],
252+
],
253+
];
232254
}
233255

234256
unset($schema['items']);
@@ -239,7 +261,7 @@ public function buildSchema(string $className, string $format = 'jsonapi', strin
239261

240262
$schema['description'] = "$definitionName collection.";
241263
$schema['allOf'] = [
242-
['$ref' => $prefix.self::COLLECTION_BASE_SCHEMA_NAME],
264+
['$ref' => $prefix.(false === $operation->getPaginationEnabled() ? self::COLLECTION_BASE_SCHEMA_NAME_NO_PAGINATION : self::COLLECTION_BASE_SCHEMA_NAME)],
243265
['type' => 'object', 'properties' => [
244266
'data' => [
245267
'type' => 'array',

0 commit comments

Comments
 (0)