0

0

在API Platform中为嵌套实体创建自定义筛选器端点

DDD

DDD

发布时间:2025-10-01 17:04:19

|

196人浏览过

|

来源于php中文网

原创

在api platform中为嵌套实体创建自定义筛选器端点

本文详细介绍了如何在Symfony和API Platform项目中,为嵌套实体(如产品模型中的品牌和产品类型)创建自定义API端点,以获取所有独特的品牌和产品类型列表。通过配置自定义操作、编写仓库方法进行数据查询,并创建控制器动作来整合并返回所需格式的数据,实现前端筛选器功能。

1. 需求分析与问题背景

在构建API驱动的应用程序时,经常需要为前端提供数据筛选功能。例如,一个产品列表可能需要按品牌或产品类型进行筛选。当这些筛选条件(如品牌和产品类型)作为嵌套实体(例如,Product 实体通过 ProductModel 关联到 Brand 和 ProductType)存在时,直接通过API Platform的默认机制获取所有唯一的品牌和产品类型列表会比较复杂。本教程将指导您如何创建一个自定义端点,以返回一个包含所有独特品牌和产品类型的JSON对象,格式如下:

{
    "brands": [
        "Agilent",
        "Comtr",
        "Anot"
    ],
    "types": [
        "Accelerometer",
        "Sonometer",
        "Micro-amplifier"
    ]
}

我们将使用API Platform的自定义操作(Custom Operations)功能,结合Symfony控制器和Doctrine实体仓库来完成此任务。

2. 定义自定义API Platform操作

首先,我们需要在相关的实体上定义一个自定义的集合操作(collection operation)。由于品牌(idBrand)和产品类型(idProductType)都直接关联在 ProductModel 实体上,我们将把这个自定义操作添加到 ProductModel 实体对应的 ApiResource 注解中。

打开 App\Entity\ProductModel 类,修改其 ApiResource 注解,添加一个名为 filters 的自定义操作:

关键点解释:

  • "filters": 这是我们自定义操作的名称,您可以根据实际情况命名。
  • "method"="GET": 指定这是一个HTTP GET请求。
  • "path"="/product_models/filters": 定义了此自定义端点的URL路径。
  • "controller"=App\Controller\Action\DistinctFiltersAction::class: 指定处理此请求的自定义控制器类。
  • "openapi_context": 用于OpenAPI/Swagger文档的配置,这里添加了一个摘要信息。
  • "read"=false: 这是一个重要设置,它告诉API Platform此操作不是为了检索单个资源实例,而是处理集合级别的逻辑。

3. 实现仓库方法获取独特数据

接下来,我们需要在 ProductModel 对应的仓库(ProductModelRepository)中添加方法,用于从数据库中查询所有独特的品牌名称和产品类型名称。

打开 App\Repository\ProductModelRepository.php,添加以下两个方法:

createQueryBuilder('pm')
            ->select('b.name') // 选择 Brand 实体的名称属性
            ->join('pm.idBrand', 'b') // 通过 idBrand 关联到 Brand 实体
            ->groupBy('b.name') // 按品牌名称分组以获取唯一值
            ->getQuery()
            ->getSingleColumnResult(); // 返回一个简单的字符串数组
    }

    /**
     * 获取所有独特的产品类型名称列表。
     * 假设 ProductType 实体有一个 'name' 属性。
     *
     * @return array
     */
    public function getDistinctProductTypes(): array
    {
        return $this->createQueryBuilder('pm')
            ->select('pt.name') // 选择 ProductType 实体的名称属性
            ->join('pm.idProductType', 'pt') // 通过 idProductType 关联到 ProductType 实体
            ->groupBy('pt.name') // 按产品类型名称分组以获取唯一值
            ->getQuery()
            ->getSingleColumnResult(); // 返回一个简单的字符串数组
    }
}

代码说明:

Timely
Timely

一款AI时间跟踪管理工具!

下载
  • 我们使用 createQueryBuilder 来构建Doctrine查询。
  • select('b.name') 和 select('pt.name') 假设您的 Brand 实体和 ProductType 实体都包含一个名为 name 的属性来存储其名称。如果您的实体使用其他属性(例如 title 或 brandName),请相应地修改。
  • join('pm.idBrand', 'b') 和 join('pm.idProductType', 'pt') 用于将 ProductModel 实体与其关联的 Brand 和 ProductType 实体连接起来。
  • groupBy('b.name') 和 groupBy('pt.name') 是获取唯一值的关键。在SQL中,通过 GROUP BY 子句可以对结果集进行分组,结合 SELECT 选定的列,可以有效地获取该列的所有唯一值。
  • getSingleColumnResult() 是一个便捷的方法,它会返回查询结果的第一个(也是唯一一个)列作为一个简单的索引数组。

4. 创建自定义控制器动作

最后,我们需要创建在 ApiResource 注解中指定的控制器类 App\Controller\Action\DistinctFiltersAction。这个控制器将负责调用仓库方法,并将结果格式化成所需的JSON结构。

在 src/Controller/Action/ 目录下创建 DistinctFiltersAction.php 文件(如果 Action 目录不存在,请创建):

getDistinctBrands();
        $types = $productModelRepository->getDistinctProductTypes();

        // 将结果格式化为所需的JSON结构并返回
        return new JsonResponse([
            'brands' => $brands,
            'types' => $types,
        ]);
    }
}

代码说明:

  • AbstractController: 继承自Symfony的抽象控制器,可以方便地访问服务容器。
  • __invoke(): 这是一个PHP的魔术方法,当对象被当作函数调用时会自动执行。API Platform会直接调用此方法。
  • ProductModelRepository $productModelRepository: 通过依赖注入,Symfony会自动将 ProductModelRepository 实例传递给控制器。
  • JsonResponse: Symfony提供的类,用于方便地返回JSON格式的响应。

注意事项:

  • 路由冲突: 在 ApiResource 注解中定义了 path,通常情况下不需要在控制器中再次使用 @Route 注解。但是,如果您希望在不依赖 ApiResource 注解的情况下也能访问此控制器(例如,作为常规Symfony路由),或者需要更细致的路由配置,可以添加。在本教程中,ApiResource 的定义已足够。
  • 命名空间: 确保控制器文件位于正确的命名空间 App\Controller\Action 下。

5. 测试与验证

完成以上步骤后,您可以通过以下方式验证您的自定义端点:

  1. 更新Composer和清除缓存:
    composer dump-autoload
    php bin/console cache:clear
  2. 查看路由: 运行Symfony的路由调试命令,确认您的自定义路由已正确注册:
    php bin/console debug:router

    您应该能看到类似 /product_models/filters 的路由。

  3. 访问端点: 使用您的API客户端(如Postman、Insomnia或浏览器)访问 GET /product_models/filters 端点(例如 http://localhost:8000/api/product_models/filters),您将获得一个包含独特品牌和产品类型列表的JSON响应。

6. 总结

通过结合API Platform的自定义操作、Doctrine实体仓库的强大查询能力以及Symfony控制器的灵活性,我们成功地为嵌套实体创建了一个高效且结构化的筛选器数据端点。这种方法不仅满足了前端对独特数据列表的需求,也保持了API的整洁和专业性。在实际项目中,您可以根据需要扩展这些仓库方法,例如添加分页、排序或更复杂的筛选逻辑,以适应不断变化的业务需求。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2042

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1373

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1283

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

951

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1406

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1231

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1440

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1303

2023.11.13

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

150

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.2万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号