如何使用不与任何特定实体相关的参数编写自定义端点

时间:2019-06-13 23:27:24

标签: symfony api-platform.com

我正在尝试编写自定义GET端点,该端点必须具有一个或多个自定义参数,但不能建立在特定实体之上。

类似: / assets / {device_id} / {scene_id} / {maybe_other_param}

我想这只是自己的控制器类,我在其中进行一些操作,从输入中计算值,手动读取一些数据并返回实体数组。 我只得到一个Asset实体,但是它需要{device}和{scene}才能成为该实体的属性...

我不希望它通过其属性作为带有过滤器的暴露实体来工作,我只需要在API中看到简单的终结点,就象需要一些参数,处理和返回json的普通自定义控制器一样。

这听起来很简单,但是我阅读了大量的文档和示例,但仍然一无所获。在API平台上甚至有可能吗?

1 个答案:

答案 0 :(得分:0)

如果要将路径中的参数直接传递到控制器,则需要使用“ read” = false配置操作。这是我可以通过这种收集操作使用的最简单的资产资源:

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();
    }
}

我使用以下Contoller类对其进行了测试:

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];
    }
}

也适用于GET项目操作。对于以输出为资源的收集操作,请不要从中删除任何默认的“获取”操作,否则IriConverter无法生成必要的iri。如果您不希望必须输出DTO或它不是资源,则将output =配置为输出的类。然后,您也需要对此进行修改,有关集合操作的示例,请参见我的tutorial的Chapter9-api分支。有关POST操作,请参见我对this question的回答。