diff --git a/src/JsonSchema/SchemaFactory.php b/src/JsonSchema/SchemaFactory.php index 097eaddd4b8..f9c75720f8f 100644 --- a/src/JsonSchema/SchemaFactory.php +++ b/src/JsonSchema/SchemaFactory.php @@ -18,6 +18,7 @@ use ApiPlatform\Metadata\CollectionOperationInterface; use ApiPlatform\Metadata\HttpOperation; use ApiPlatform\Metadata\Operation; +use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface; use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; @@ -33,6 +34,9 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareInterface { use ResourceMetadataTrait; + + private const PATCH_SCHEMA_POSTFIX = '.patch'; + private ?TypeFactoryInterface $typeFactory = null; private ?SchemaFactoryInterface $schemaFactory = null; // Edge case where the related resource is not readable (for example: NotExposed) but we have groups to read the whole related object @@ -88,6 +92,12 @@ public function buildSchema(string $className, string $format = 'json', string $ return $schema; } + $isJsonMergePatch = 'json' === $format && $operation instanceof Patch && Schema::TYPE_INPUT === $type; + + if ($isJsonMergePatch) { + $definitionName .= self::PATCH_SCHEMA_POSTFIX; + } + if (!isset($schema['$ref']) && !isset($schema['type'])) { $ref = Schema::VERSION_OPENAPI === $version ? '#/components/schemas/'.$definitionName : '#/definitions/'.$definitionName; if ($forceCollection || ('POST' !== $method && $operation instanceof CollectionOperationInterface)) { @@ -136,7 +146,7 @@ public function buildSchema(string $className, string $format = 'json', string $ } $normalizedPropertyName = $this->nameConverter ? $this->nameConverter->normalize($propertyName, $inputOrOutputClass, $format, $serializerContext) : $propertyName; - if ($propertyMetadata->isRequired()) { + if ($propertyMetadata->isRequired() && !$isJsonMergePatch) { $definition['required'][] = $normalizedPropertyName; }