Skip to content

Commit eec8464

Browse files
committed
fix(hydra): require @id and @type for output json schema
1 parent e52e825 commit eec8464

File tree

2 files changed

+22
-18
lines changed

2 files changed

+22
-18
lines changed

src/Hydra/JsonSchema/SchemaFactory.php

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,18 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI
3636
use ResourceMetadataTrait;
3737
use SchemaUriPrefixTrait;
3838

39-
private const ITEM_BASE_SCHEMA_NAME = 'HydraItemBaseSchema';
40-
private const ITEM_BASE_SCHEMA_OUTPUT_NAME = 'HydraOutputBaseSchema';
41-
private const COLLECTION_BASE_SCHEMA_NAME = 'HydraCollectionBaseSchema';
39+
private const INPUT_ITEM_SCHEMA_NAME = 'HydraInputItemSchema';
40+
private const OUTPUT_ITEM_SCHEMA_NAME = 'HydraOutputItemSchema';
41+
private const COLLECTION_SCHEMA_NAME = 'HydraCollectionSchema';
4242
private const BASE_PROP = [
4343
'type' => 'string',
4444
];
4545
private const BASE_PROPS = [
4646
'@id' => self::BASE_PROP,
4747
'@type' => self::BASE_PROP,
4848
];
49-
private const ITEM_BASE_SCHEMA = [
49+
// This is the base for both input and output, and serves as the complete definition for an INPUT schema.
50+
private const BASE_ITEM_SCHEMA = [
5051
'type' => 'object',
5152
'properties' => [
5253
'@context' => [
@@ -70,10 +71,10 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI
7071
],
7172
] + self::BASE_PROPS,
7273
];
73-
74-
private const ITEM_BASE_SCHEMA_OUTPUT = [
74+
// The OUTPUT schema is the base schema with the addition of required fields.
75+
private const OUTPUT_ITEM_SCHEMA = [
7576
'required' => ['@id', '@type'],
76-
] + self::ITEM_BASE_SCHEMA;
77+
] + self::BASE_ITEM_SCHEMA;
7778

7879
/**
7980
* @var array<string, true>
@@ -104,9 +105,10 @@ public function __construct(
104105
*/
105106
public function buildSchema(string $className, string $format = 'jsonld', string $type = Schema::TYPE_OUTPUT, ?Operation $operation = null, ?Schema $schema = null, ?array $serializerContext = null, bool $forceCollection = false): Schema
106107
{
107-
if ('jsonld' !== $format || 'input' === $type) {
108+
if ('jsonld' !== $format) {
108109
return $this->schemaFactory->buildSchema($className, $format, $type, $operation, $schema, $serializerContext, $forceCollection);
109110
}
111+
110112
if (!$this->isResourceClass($className)) {
111113
$operation = null;
112114
$inputOrOutputClass = null;
@@ -140,10 +142,11 @@ public function buildSchema(string $className, string $format = 'jsonld', string
140142
return $schema;
141143
}
142144

143-
$baseName = Schema::TYPE_OUTPUT === $type ? self::ITEM_BASE_SCHEMA_NAME : self::ITEM_BASE_SCHEMA_OUTPUT_NAME;
145+
$isOutput = Schema::TYPE_OUTPUT === $type;
146+
$baseName = $isOutput ? self::OUTPUT_ITEM_SCHEMA_NAME : self::INPUT_ITEM_SCHEMA_NAME;
144147

145148
if (!isset($definitions[$baseName])) {
146-
$definitions[$baseName] = Schema::TYPE_OUTPUT === $type ? self::ITEM_BASE_SCHEMA_OUTPUT : self::ITEM_BASE_SCHEMA;
149+
$definitions[$baseName] = $isOutput ? self::OUTPUT_ITEM_SCHEMA : self::BASE_ITEM_SCHEMA;
147150
}
148151

149152
$allOf = new \ArrayObject(['allOf' => [
@@ -171,7 +174,7 @@ public function buildSchema(string $className, string $format = 'jsonld', string
171174

172175
$hydraPrefix = $this->getHydraPrefix($serializerContext + $this->defaultContext);
173176

174-
if (!isset($definitions[self::COLLECTION_BASE_SCHEMA_NAME])) {
177+
if (!isset($definitions[self::COLLECTION_SCHEMA_NAME])) {
175178
switch ($schema->getVersion()) {
176179
// JSON Schema + OpenAPI 3.1
177180
case Schema::VERSION_OPENAPI:
@@ -184,7 +187,7 @@ public function buildSchema(string $className, string $format = 'jsonld', string
184187
break;
185188
}
186189

187-
$definitions[self::COLLECTION_BASE_SCHEMA_NAME] = [
190+
$definitions[self::COLLECTION_SCHEMA_NAME] = [
188191
'type' => 'object',
189192
'required' => [
190193
$hydraPrefix.'member',
@@ -261,7 +264,7 @@ public function buildSchema(string $className, string $format = 'jsonld', string
261264
$schema['type'] = 'object';
262265
$schema['description'] = "$definitionName collection.";
263266
$schema['allOf'] = [
264-
['$ref' => $prefix.self::COLLECTION_BASE_SCHEMA_NAME],
267+
['$ref' => $prefix.self::COLLECTION_SCHEMA_NAME],
265268
[
266269
'type' => 'object',
267270
'properties' => [
@@ -285,3 +288,4 @@ public function setSchemaFactory(SchemaFactoryInterface $schemaFactory): void
285288
}
286289
}
287290
}
291+

tests/Functional/JsonSchema/JsonLdJsonSchemaTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function testSubSchemaJsonLd(): void
5151
$expectedBagOfTestsSchema = new \ArrayObject([
5252
'allOf' => [
5353
[
54-
'$ref' => '#/definitions/HydraItemBaseSchema',
54+
'$ref' => '#/definitions/HydraOutputItemSchema',
5555
],
5656
new \ArrayObject([
5757
'type' => 'object',
@@ -106,7 +106,7 @@ public function testSubSchemaJsonLd(): void
106106
$expectedTestEntitySchema = new \ArrayObject([
107107
'allOf' => [
108108
[
109-
'$ref' => '#/definitions/HydraItemBaseSchema',
109+
'$ref' => '#/definitions/HydraOutputItemSchema',
110110
],
111111
new \ArrayObject([
112112
'type' => 'object',
@@ -152,10 +152,10 @@ public function testSchemaJsonLdCollection(): void
152152
$this->assertArrayHasKey('BagOfTests.jsonld-read', $schema['definitions']);
153153
$this->assertArrayHasKey('NonResourceTestEntity.jsonld-read', $schema['definitions']);
154154
$this->assertArrayHasKey('TestEntity.jsonld-read', $schema['definitions']);
155-
$this->assertArrayHasKey('HydraItemBaseSchema', $schema['definitions']);
156-
$this->assertArrayHasKey('HydraCollectionBaseSchema', $schema['definitions']);
155+
$this->assertArrayHasKey('HydraOutputItemSchema', $schema['definitions']);
156+
$this->assertArrayHasKey('HydraCollectionSchema', $schema['definitions']);
157157

158-
$this->assertEquals(['$ref' => '#/definitions/HydraCollectionBaseSchema'], $schema['allOf'][0]);
158+
$this->assertEquals(['$ref' => '#/definitions/HydraCollectionSchema'], $schema['allOf'][0]);
159159
$this->assertEquals(['$ref' => '#/definitions/BagOfTests.jsonld-read'], $schema['allOf'][1]['properties']['hydra:member']['items']);
160160
}
161161

0 commit comments

Comments
 (0)