当前位置: 首页 > 知识库问答 >
问题:

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

宗政昱
2023-03-14

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

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

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

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

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

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

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

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

所以,主要问题是我应该使用哪种方法或最佳实践来实现与任何实体无关的自定义操作。使用DTO进行请求和响应将是很棒的。

共有1个答案

赵镜
2023-03-14

你没有被强迫使用实体。用< code>@ApiResource批注标记的类可能不是实体。实际上,如果你的应用比基本的CRUD聪明,你应该避免将实体标记为ApiResource。

因为您想使用POST HTTP方法(用于创建资源项),所以可以这样做。

1)定义描述搜索字段的类,它将是您的< code>@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)创建将填充DataPersister接口以处理业务逻辑的类。它将被框架调用,因为你发出 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
    }
}

这样,您将根据请求收到结果。

 类似资料:
  • 这些方法有什么区别吗?特别是最后一种方法是什么?一个比另一个好用吗?

  • 问题内容: 我已经看到以下内容: AngularJS文档也提到了这一点,我不太了解。 这些方法之间有什么区别吗?特别是Angular文档的最后一种方法是做什么的?一个比另一个更好用吗? 问题答案: 它们大致相同,但有一些区别: 如果您 在页面末尾 (而不是在标题中)加载 了 脚本,这将起作用。 否则,在引导应用程序时将不会加载DOM(不会编译任何模板,指令不会有任何效果)。 此作品:plnkr 这

  • 问题内容: 因为Linux(及其变体)的字体集与Windows和Mac OS X完全不同,所以是否有人有创建跨平台字体家族的经验- 理想地找到与上述操作系统中常见字体等效的字体? 如果是这样,最好的路线是什么? 问题答案: 以下是一些用于PC,Mac和Linux的最新安装字体的良好最新列表: Sans Serif字体采样器和调查结果 Serif字体采样器和调查结果 希望这对您的决定有所帮助!

  • 我需要创建一个GETendpoint来返回通过超文本传输协议客户端从另一个应用程序获取的资源,而不是基于实体。我获取的资源是一个数组: 然后我需要查询数据库以获取一些数据以添加到资源数组中。 所以我在中创建了它: 但是现在,我希望我的api返回json api响应格式:https://jsonapi.org/. 基于实体的资源,api平台完全支持。我不需要做太多。我只是在实体类中添加“key”并配

  • 我有一个客户端anger-js应用程序。我有一个服务器端nodejs应用程序接口。客户端和服务器端应用程序位于不同的域上。客户端使用API获取或发布一些数据。客户端还需要从服务器端获取图像并在浏览器中显示它们。 我使用护照nodejs模块进行身份验证。我不知道哪种身份验证策略更适合我。我认为有两种类型的身份验证策略:基于令牌的和基于cookie的。我认为这两种类型在我的情况下都没用: > < li

  • 我对Symfony和API平台很陌生。我正在尝试创建一个自定义资源/操作,该资源/操作接收请求的正文,根据值从数据库中获取数据,然后将实体集合返回给客户端。 示例:具有以下正文的 请求: 根据这些属性,我想查询数据,进行计算,然后返回数据。 我试图弄清楚如何使这个API平台的方式。我已经在谷歌上搜索并在留档中寻找了几个小时,但我找不到实现这一目标的方法。 我尝试使用和如下所示的控制器查询数据: 但