Skip to content

Commit 5b59f89

Browse files
authored
fix(jsonschema/jsonld): make @id and @type properties required only in the JSON-LD schema for output (#7397)
1 parent e52e825 commit 5b59f89

File tree

3 files changed

+19
-15
lines changed

3 files changed

+19
-15
lines changed

src/Hydra/JsonSchema/SchemaFactory.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI
3737
use SchemaUriPrefixTrait;
3838

3939
private const ITEM_BASE_SCHEMA_NAME = 'HydraItemBaseSchema';
40-
private const ITEM_BASE_SCHEMA_OUTPUT_NAME = 'HydraOutputBaseSchema';
4140
private const COLLECTION_BASE_SCHEMA_NAME = 'HydraCollectionBaseSchema';
4241
private const BASE_PROP = [
4342
'type' => 'string',
@@ -69,11 +68,8 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI
6968
],
7069
],
7170
] + self::BASE_PROPS,
72-
];
73-
74-
private const ITEM_BASE_SCHEMA_OUTPUT = [
7571
'required' => ['@id', '@type'],
76-
] + self::ITEM_BASE_SCHEMA;
72+
];
7773

7874
/**
7975
* @var array<string, true>
@@ -104,7 +100,15 @@ public function __construct(
104100
*/
105101
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
106102
{
107-
if ('jsonld' !== $format || 'input' === $type) {
103+
// The input schema must not include `@id` or `@type` as required fields, so it should be a pure JSON schema.
104+
// Strictly speaking, it is possible to include `@id` or `@context` in the input,
105+
// but the generated JSON Schema does not include `"additionalProperties": false` by default,
106+
// so it is possible to include `@id` or `@context` in the input even if the input schema is a JSON schema.
107+
if (Schema::TYPE_INPUT === $type) {
108+
$format = 'json';
109+
}
110+
111+
if ('jsonld' !== $format) {
108112
return $this->schemaFactory->buildSchema($className, $format, $type, $operation, $schema, $serializerContext, $forceCollection);
109113
}
110114
if (!$this->isResourceClass($className)) {
@@ -140,10 +144,10 @@ public function buildSchema(string $className, string $format = 'jsonld', string
140144
return $schema;
141145
}
142146

143-
$baseName = Schema::TYPE_OUTPUT === $type ? self::ITEM_BASE_SCHEMA_NAME : self::ITEM_BASE_SCHEMA_OUTPUT_NAME;
147+
$baseName = self::ITEM_BASE_SCHEMA_NAME;
144148

145149
if (!isset($definitions[$baseName])) {
146-
$definitions[$baseName] = Schema::TYPE_OUTPUT === $type ? self::ITEM_BASE_SCHEMA_OUTPUT : self::ITEM_BASE_SCHEMA;
150+
$definitions[$baseName] = self::ITEM_BASE_SCHEMA;
147151
}
148152

149153
$allOf = new \ArrayObject(['allOf' => [

tests/Functional/JsonSchema/JsonSchemaTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,24 +134,24 @@ public function testArraySchemaWithReference(): void
134134

135135
$schema = $this->schemaFactory->buildSchema(BagOfTests::class, 'jsonld', Schema::TYPE_INPUT);
136136

137-
$this->assertEquals($schema['definitions']['BagOfTests.jsonld-write']['properties']['tests'], new \ArrayObject([
137+
$this->assertEquals($schema['definitions']['BagOfTests-write']['properties']['tests'], new \ArrayObject([
138138
'type' => 'string',
139139
'foo' => 'bar',
140140
]));
141141

142-
$this->assertEquals($schema['definitions']['BagOfTests.jsonld-write']['properties']['nonResourceTests'], new \ArrayObject([
142+
$this->assertEquals($schema['definitions']['BagOfTests-write']['properties']['nonResourceTests'], new \ArrayObject([
143143
'type' => 'array',
144144
'items' => [
145-
'$ref' => '#/definitions/NonResourceTestEntity.jsonld-write',
145+
'$ref' => '#/definitions/NonResourceTestEntity-write',
146146
],
147147
]));
148148

149-
$this->assertEquals($schema['definitions']['BagOfTests.jsonld-write']['properties']['description'], new \ArrayObject([
149+
$this->assertEquals($schema['definitions']['BagOfTests-write']['properties']['description'], new \ArrayObject([
150150
'maxLength' => 255,
151151
]));
152152

153-
$this->assertEquals($schema['definitions']['BagOfTests.jsonld-write']['properties']['type'], new \ArrayObject([
154-
'$ref' => '#/definitions/TestEntity.jsonld-write',
153+
$this->assertEquals($schema['definitions']['BagOfTests-write']['properties']['type'], new \ArrayObject([
154+
'$ref' => '#/definitions/TestEntity-write',
155155
]));
156156
}
157157

tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public function testWritableNonResourceRef(): void
141141
$result = $this->tester->getDisplay();
142142
$json = json_decode($result, associative: true);
143143

144-
$this->assertEquals($json['definitions']['SaveProduct.jsonld']['properties']['codes']['items']['$ref'], '#/definitions/ProductCode.jsonld');
144+
$this->assertEquals($json['definitions']['SaveProduct']['properties']['codes']['items']['$ref'], '#/definitions/ProductCode');
145145
}
146146

147147
/**

0 commit comments

Comments
 (0)