Api Platform SearchFilter查询PostgreSQL JSON列roles的正确URL格式
解决PostgreSQL JSON列Api Platform精确匹配问题
问题根源
PostgreSQL的json类型不支持直接使用=运算符进行等值匹配,而Api Platform的SearchFilter默认会生成=的SQL语句,这就是报错的核心原因。jsonb类型才原生支持等值比较,这是最直接的解决方案。
解决方案
1. 后端调整(必须步骤)
修改实体类中roles字段的ORM类型为jsonb:
#[ApiFilter(SearchFilter::class, properties: ['roles' => 'exact'])] #[ORM\Column(type: 'jsonb')] // 将原json类型替换为jsonb public ?array $roles = [];
执行数据库迁移,更新字段类型。
2. 前端正确的URL格式
无需添加单引号,直接传递URL编码后的JSON数组即可:
https://.../users?roles=%5B%22ROLE_ADMIN%22%5D
解码后对应的参数值是["ROLE_ADMIN"],Api Platform会自动将其解析为数组并生成正确的jsonb等值匹配SQL。
备选方案(不修改字段类型)
如果无法将json改为jsonb,需要自定义过滤器逻辑,在DQL中显式将json转为文本进行匹配:
// 自定义过滤器示例 public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null) { $request = $this->requestStack->getCurrentRequest(); $roles = $request->query->get('roles'); if (!$roles) return; $alias = $queryBuilder->getRootAliases()[0]; $paramName = $queryNameGenerator->generateParameterName('roles'); // 将json字段转为文本后执行匹配 $queryBuilder->andWhere("$alias.roles::text = :$paramName"); $queryBuilder->setParameter($paramName, $roles); }
此时前端URL同样传递URL编码后的JSON字符串(无需单引号):
https://.../users?roles=%5B%22ROLE_ADMIN%22%5D
内容的提问来源于stack exchange,提问作者Khribi Wessim
相关产品推荐
相关产品推荐

