How to write custom endpoints with parameters not related to any specific entity

前端 未结 1 1613
有刺的猬
有刺的猬 2021-01-07 10:55

I\'m trying to write custom GET endpoints, which must have one or more custom parameters, but not built on top of specific entity.

Something like: /assets/{device_id

相关标签:
1条回答
  • 2021-01-07 11:04

    If you want the parameters from the path to be passed to your Controller directly you need to configure the operation with "read"=false. Here is the simpelest Asset resource i could make to work with such a collection operation:

    namespace App\Entity;
    
    use ApiPlatform\Core\Annotation\ApiResource;
    use ApiPlatform\Core\Annotation\ApiProperty;
    use App\Controller\GetAssetCollectionByPathParams;
    
    /**
     * @ApiResource(
     *     collectionOperations={
     *         "get",
     *         "get_by_path_params"={
     *             "method"="GET",
     *             "controller"=GetAssetCollectionByPathParams::class,
     *             "path"="/assets/{device_id}/{scene_id}/{maybe_other_param?}",
     *             "read"=false,
     *             "pagination_enabled"=false,
     *             "openapi_context"={
     *                 "summary"="Get by path parameters",
     *                 "parameters"={
     *                     {
     *                         "name" = "device_id",
     *                         "in" = "path",
     *                         "required" = true,
     *                         "type" = "integer"
     *                     },
     *                     {
     *                         "name" = "scene_id",
     *                         "in" = "path",
     *                         "required" = true,
     *                         "type" = "string"
     *                     },
     *                     {
     *                         "name" = "maybe_other_param",
     *                         "in" = "path",
     *                         "required" = false,
     *                         "type" = "string"
     *                     }
     *                 }
     *             }
     *         }
     *     },
     *     itemOperations={
     *         "get"
     *     }
     * )
     */
    class Asset
    {
    
        /** @var string */
        public $description;
    
        /**
         * @return int
         * @ApiProperty(identifier=true)
         */
        public function getId()
        {
            return time();
        }
    }
    

    I tested it with the following Contoller class:

    namespace App\Controller;
    
    use App\Entity\Asset;
    
    class GetAssetCollectionByPathParams
    {
        /**
         * @return Asset[]
         */
        public function __invoke($device_id, $scene_id, $maybe_other_param=null) :array
        {
            $result = new Asset();
            $result->description = "GetAssetCollectionByPathParams result for device_id: $device_id, scene_id: $scene_id, maybe_other_param: $maybe_other_param";
            return [$result];
        }
    }
    

    Also works for GET item operations. With collection operations whose output is a resource don't remove any of the default "get" operations from otherwise the IriConverter can not produce the necessary iri's. If you don't want that you must output a DTO or so that is not a resource and configure output= to the class of the output. Then you need to correct the swagger docs for that too, see chapter9-api branch of my tutorial for an example with a collection operaton. For a POST operation see my answer to this question.

    0 讨论(0)
提交回复
热议问题