API Platform自定义归一化器新增字段的文档添加方法咨询
Nice catch! Since your avatar field is injected dynamically via a custom normalizer (rather than being a native property on the User entity), API Platform doesn't automatically pick it up for inclusion in the API documentation. Here are two reliable ways to add its type, example, and descriptive details:
1. Use a Property Metadata Extension (Recommended)
This approach integrates your custom field's metadata directly with the User entity's existing schema, keeping your documentation consistent and maintainable.
First, create a metadata extension class that decorates API Platform's default property metadata factory:
<?php namespace App\Metadata; use ApiPlatform\Metadata\ApiProperty; use ApiPlatform\Metadata\Factory\ApiPropertyMetadataFactoryInterface; use App\Entity\User; class UserAvatarMetadataExtension implements ApiPropertyMetadataFactoryInterface { private $decorated; public function __construct(ApiPropertyMetadataFactoryInterface $decorated) { $this->decorated = $decorated; } public function create(string $resourceClass, string $property, array $options = []): ApiProperty { $propertyMetadata = $this->decorated->create($resourceClass, $property, $options); // Target the User entity's dynamic avatar field if ($resourceClass === User::class && $property === 'avatar') { $propertyMetadata = $propertyMetadata ->withType('string') ->withDescription('Absolute URL pointing to the user\'s avatar image') ->withExample('https://your-app-domain.com/uploads/avatars/john-doe-profile.jpg') ->withNullable(true); // Mark as nullable since users might not have an avatar } return $propertyMetadata; } }
Then register the service in your services.yaml to decorate the default factory:
services: App\Metadata\UserAvatarMetadataExtension: decorates: api_platform.metadata.property.metadata_factory arguments: ['@.inner']
2. Modify the OpenAPI Document Directly
If you need more granular control (e.g., adding the field only to specific API operations), you can extend the OpenAPI factory to manually inject the field into the schema:
Create an OpenAPI extension class:
<?php namespace App\OpenApi; use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface; use ApiPlatform\OpenApi\Model\Schema; use ApiPlatform\OpenApi\OpenApi; class UserAvatarOpenApiExtension implements OpenApiFactoryInterface { private $decorated; public function __construct(OpenApiFactoryInterface $decorated) { $this->decorated = $decorated; } public function __invoke(array $context = []): OpenApi { $openApi = $this->decorated->__invoke($context); $schemas = $openApi->getComponents()->getSchemas(); // Add avatar to the main User schema if (isset($schemas['User'])) { $schemas['User']->setProperty('avatar', new Schema( type: 'string', format: 'uri', description: 'Absolute URL to the user\'s avatar image', example: 'https://your-app-domain.com/uploads/avatars/jane-smith-profile.png', nullable: true )); } // If you have a read-specific schema (e.g., UserRead), add it there too if (isset($schemas['UserRead'])) { $schemas['UserRead']->setProperty('avatar', new Schema( type: 'string', format: 'uri', description: 'Absolute URL to the user\'s avatar image', example: 'https://your-app-domain.com/uploads/avatars/jane-smith-profile.png', nullable: true )); } return $openApi; } }
Register the service:
services: App\OpenApi\UserAvatarOpenApiExtension: decorates: api_platform.openapi.factory arguments: ['@.inner']
Quick Note
Don't forget to clear your Symfony cache after implementing either solution:
php bin/console cache:clear
内容的提问来源于stack exchange,提问作者StockBreak

