From 6ac4f078727ae3866b0ab8ac91c7565234042e11 Mon Sep 17 00:00:00 2001 From: Krystian Marcisz Date: Sat, 30 Apr 2022 20:25:41 +0200 Subject: [PATCH] [Docs] Add PHP Attributes examples (#1985) * [Docs] Add PHP Attributes examples * Fix namespaces --- Resources/doc/index.rst | 274 +++++++++++++++++++++++++++++----------- 1 file changed, 203 insertions(+), 71 deletions(-) diff --git a/Resources/doc/index.rst b/Resources/doc/index.rst index ac86238..a171845 100644 --- a/Resources/doc/index.rst +++ b/Resources/doc/index.rst @@ -17,6 +17,8 @@ This bundle supports *Symfony* route requirements, PHP annotations, `Swagger-Php For models, it supports the `Symfony serializer`_ , the `JMS serializer`_ and the `willdurand/Hateoas`_ library. It does also support `Symfony form`_ types. +Attributes are supported from version 4.7 and PHP 8.1. + Migrate from 3.x to 4.0 ----------------------- @@ -137,45 +139,91 @@ You can configure global information in the bundle configuration ``documentation To document your routes, you can use the SwaggerPHP annotations and the ``Nelmio\ApiDocBundle\Annotation\Model`` annotation in your controllers:: - namespace AppBundle\Controller; +.. configuration-block:: - use AppBundle\Entity\User; - use AppBundle\Entity\Reward; - use Nelmio\ApiDocBundle\Annotation\Model; - use Nelmio\ApiDocBundle\Annotation\Security; - use OpenApi\Annotations as OA; - use Symfony\Component\Routing\Annotation\Route; + .. code-block:: php-annotations + + namespace AppBundle\Controller; - class UserController - { - /** - * List the rewards of the specified user. - * - * This call takes into account all confirmed awards, but not pending or refused awards. - * - * @Route("/api/{user}/rewards", methods={"GET"}) - * @OA\Response( - * response=200, - * description="Returns the rewards of an user", - * @OA\JsonContent( - * type="array", - * @OA\Items(ref=@Model(type=Reward::class, groups={"full"})) - * ) - * ) - * @OA\Parameter( - * name="order", - * in="query", - * description="The field used to order rewards", - * @OA\Schema(type="string") - * ) - * @OA\Tag(name="rewards") - * @Security(name="Bearer") - */ - public function fetchUserRewardsAction(User $user) + use AppBundle\Entity\User; + use AppBundle\Entity\Reward; + use Nelmio\ApiDocBundle\Annotation\Model; + use Nelmio\ApiDocBundle\Annotation\Security; + use OpenApi\Annotations as OA; + use Symfony\Component\Routing\Annotation\Route; + + class UserController { - // ... + /** + * List the rewards of the specified user. + * + * This call takes into account all confirmed awards, but not pending or refused awards. + * + * @Route("/api/{user}/rewards", methods={"GET"}) + * @OA\Response( + * response=200, + * description="Returns the rewards of an user", + * @OA\JsonContent( + * type="array", + * @OA\Items(ref=@Model(type=Reward::class, groups={"full"})) + * ) + * ) + * @OA\Parameter( + * name="order", + * in="query", + * description="The field used to order rewards", + * @OA\Schema(type="string") + * ) + * @OA\Tag(name="rewards") + * @Security(name="Bearer") + */ + public function fetchUserRewardsAction(User $user) + { + // ... + } } - } + + .. code-block:: php-attributes + + namespace AppBundle\Controller; + + use AppBundle\Entity\User; + use AppBundle\Entity\Reward; + use Nelmio\ApiDocBundle\Annotation\Model; + use Nelmio\ApiDocBundle\Annotation\Security; + use OpenApi\Attributes as OA; + use Symfony\Component\Routing\Annotation\Route; + + class UserController + { + /** + * List the rewards of the specified user. + * + * This call takes into account all confirmed awards, but not pending or refused awards. + */ + #[Route('/api/{user}/rewards', methods=['GET'])] + #[OA\Response( + response: 200, + description: 'Returns the rewards of an user', + content: new OA\JsonContent( + type: 'array', + items: new OA\Items(ref: new Model(type: AlbumDto::class, groups: ['full'])) + ) + )] + #[OA\Parameter( + name: 'order', + in: 'query', + description: 'The field used to order rewards', + schema: new OA\Schema(type: 'string') + )] + #[OA\Tag(name: 'rewards')] + #[Security(name: 'Bearer')] + public function fetchUserRewardsAction(User $user) + { + // ... + } + } + The normal PHPdoc block on the controller method is used for the summary and description. @@ -199,21 +247,46 @@ This annotation has two options: * ``type`` to specify your model's type:: - /** - * @OA\Response( - * response=200, - *     @Model(type=User::class) - * ) - */ +.. configuration-block:: + + .. code-block:: php-annotations + + /** + * @OA\Response( + * response=200, + *     @Model(type=User::class) + * ) + */ + + .. code-block:: php-attributes + + #[OA\Response( + response: 200, + description: 'Successful response', + content: new Model(type: User::class) + )] * ``groups`` to specify the serialization groups used to (de)serialize your model:: - /** - * @OA\Response( - * response=200, - *     @Model(type=User::class, groups={"non_sensitive_data"}) - * ) - */ + +.. configuration-block:: + + .. code-block:: php-annotations + + /** + * @OA\Response( + * response=200, + *     @Model(type=User::class, groups={"non_sensitive_data"}) + * ) + */ + + .. code-block:: php-attributes + + #[OA\Response( + response: 200, + description: 'Successful response', + content: new Model(type: User::class, groups: ['non_sensitive_data']) + )] .. tip:: @@ -224,6 +297,10 @@ This annotation has two options: To use ``@Model`` directly within a ``@OA\Schema``, ``@OA\Items`` or ``@OA\Property``, you have to use the ``$ref`` field:: +.. configuration-block:: + + .. code-block:: php-annotations + /** * @OA\Response( * @OA\JsonContent(ref=@Model(type=User::class)) @@ -238,6 +315,23 @@ This annotation has two options: * )) */ + .. code-block:: php-attributes + + #[OA\Response( + content: new OA\JsonContent(ref: new Model(type: User::class)) + )] + /** + * or + */ + #[OA\Response( + content: new OA\XmlContent(example: new OA\Schema( + type: 'object', + properties: [ + new OA\Property(property: 'foo', ref: new Model(type: FooClass::class)) + ] + )) + )] + Symfony Form types ~~~~~~~~~~~~~~~~~~ @@ -288,7 +382,15 @@ General PHP objects .. code-block:: php - @OA\Schema(ref=@Model(type="App\Response\ItemResponse", groups=["Default"])), + .. configuration-block:: + + .. code-block:: php-annotations + + @OA\Schema(ref=@Model(type="App\Response\ItemResponse", groups=["Default"])), + + .. code-block:: php-attributes + + #[OA\Schema(ref: new Model(type: App\Response\ItemResponse::class, groups: ['Default']))] It will generate two different component schemas (ItemResponse, ItemResponse2), even though Default and blank are the same. This is by design. @@ -306,34 +408,64 @@ General PHP objects If you want to customize the documentation of an object's property, you can use ``@OA\Property``:: - use Nelmio\ApiDocBundle\Annotation\Model; - use OpenApi\Annotations as OA; - class User - { - /** - * @var int - * @OA\Property(description="The unique identifier of the user.") - */ - public $id; +.. configuration-block:: - /** - * @OA\Property(type="string", maxLength=255) - */ - public $username; + .. code-block:: php-annotations + + use Nelmio\ApiDocBundle\Annotation\Model; + use OpenApi\Annotations as OA; - /** - * @OA\Property(ref=@Model(type=User::class)) - */ - public $friend; + class User + { + /** + * @var int + * @OA\Property(description="The unique identifier of the user.") + */ + public $id; - /** - * @OA\Property(description="This is my coworker!") - */ - public setCoworker(User $coworker) { - // ... + /** + * @OA\Property(type="string", maxLength=255) + */ + public $username; + + /** + * @OA\Property(ref=@Model(type=User::class)) + */ + public $friend; + + /** + * @OA\Property(description="This is my coworker!") + */ + public setCoworker(User $coworker) { + // ... + } + } + + .. code-block:: php-attributes + + use Nelmio\ApiDocBundle\Annotation\Model; + use OpenApi\Attributes as OA; + + class User + { + /** + * @var int + */ + #[OA\Property(description: 'The unique identifier of the user.')] + public $id; + + #[OA\Property(type: 'string', maxLength: 255)] + public $username; + + #[OA\Property(ref: new Model(type: User::class))] + public $friend; + + #[OA\Property(description: 'This is my coworker!')] + public setCoworker(User $coworker) { + // ... + } } - } See the `OpenAPI 3.0 specification`__ to see all the available fields of ``@OA\Property``.