API 平台 - 我应该使用哪种方法来创建没有实体的自定义操作

2024-04-18

我是 API 平台的新手。我认为这很棒,但我找不到任何示例如何创建不基于任何实体的自定义端点。有很多基于实体的示例,通常都是关于 CRUD 的。但是自定义操作呢?

我需要使用一些与任何实体无关的自定义参数通过数据库创建自定义搜索。 例如。我想接收这样的 POST 请求:

{
   "from": "Paris",
   "to": "Berlin"
}

该数据未保存到数据库中,并且我没有它的实体。 在我收到这些数据后,应该有很多业务逻辑,包括通过大量数据库表进行数据库查询以及从外部源获取数据。 然后,在业务逻辑完成后,我想返回结果,该结果也是自定义的且与任何实体无关。 例如。

{
    "flights": [/* a lot of json data*/],
    "airports": [/* a lot of json data*/],
    "cities": [/* a lot of json data*/],
    .......
}

所以,我想我并不是唯一一个做类似事情的人。但我真的找不到解决方案或最佳实践来做到这一点。 在文档中,我发现了至少三种方法,但我无法实现其中任何一种。 最好的,我想最适合我的是使用自定义操作和控制器。但文档说不推荐这样做。另外,我认为我应该使用 DTO 进行请求和响应,但对于这种方法,我不确定是否可以使用它们。

我发现它使用数据传输对象的第二个方法,但这种方法需要一个实体。根据文档,我应该使用 DTO 和 DataTransformers 将 DTO 转换为实体。但我不需要实体,我不需要将它保存到数据库。我想自己处理收到的 DTO。

第三个我猜它是使用数据提供者,但我不确定它是否适合我的要求。

因此,主要问题是我应该使用哪种方法或最佳实践来实现与任何实体无关的自定义操作。使用 DTO 进行请求和响应会非常有用。


您不必被迫使用实体。标记为的类@ApiResource注释不能是实体。实际上,如果您的应用程序比基本 CRUD 更智能,您应该避免将实体标记为 ApiResource。

由于您想使用 POST HTTP 方法(用于创建资源项),您可以执行以下操作。

1)定义描述搜索字段的类以及您的搜索字段@ApiResource

<?php
// src/ApiResource/Search.php 

namespace App\ApiResource;

use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Action\NotFoundAction;
use ApiPlatform\Core\Annotation\ApiProperty;
use App\Dto\SearchResult;

/**
 * @ApiResource(
 *     itemOperations={
 *         "get"={
 *             "controller"=NotFoundAction::class,
 *             "read"=true,
 *             "output"=false,
 *         },
 *     },
 *     output=SearchResult::class
 * )
 */
class Search
{
    /**
     * @var string
     * @ApiProperty(identifier=true)
     */
    public $from;

    /** @var string */
    public $to;
}

2) 定义代表输出的DTO

<?php
// src/Dto/SearchResult.php

namespace App\Dto;

class SearchResult
{
    public $flights;
    public $airports;
    public $cities;
}

3)创建将实现的类DataPersisterInterface用于处理业务逻辑。 它会被框架调用,因为你发出 POST 请求。

<?php
// src/DataPersister/SearchService.php

declare(strict_types=1);

namespace App\DataPersister;

use ApiPlatform\Core\DataPersister\DataPersisterInterface;
use App\Dto\SearchResult;
use App\ApiResource\Search;

final class SearchService implements DataPersisterInterface
{
    public function supports($data): bool
    {
        return $data instanceof Search;
    }

    public function persist($data)
    {
        // here you have access to your request via $data
        $output = new SearchResult();
        $output->flights = ['a lot of json data'];
        $output->airports = ['a lot of json data'];
        $output->cities = ['inputData' => $data];
        return $output;
    }

    public function remove($data)
    {
        // this method just need to be presented
    }
}

这样您将收到基于请求的结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

API 平台 - 我应该使用哪种方法来创建没有实体的自定义操作 的相关文章

  • 在 OSX 上通过 dlopen 打开库时调试崩溃

    我开发的 C 应用程序有问题 该应用程序使用 dlopen 加载用户开发的库 在过去的几年里 这个应用程序已经被很多人在各种 Linux 发行版和 OSX 版本上使用 所以我假设我对 dlopen 的使用是好的 依赖它的代码也是如此 是的

随机推荐