如何通过API Platform GraphQL查询读取空间Point类型数据
解决API Platform GraphQL无法识别doctrine-spatial Point类型的方案
两种实现方案均不会修改原有Doctrine映射,可完全保留Postgres geometry类型与geometryViewer的所有能力:
方案1:自定义GraphQL标量(推荐,支持读写双向)
- 第一步:创建自定义标量类
// src/GraphQL/Type/PointType.php namespace App\GraphQL\Type; use GraphQL\Type\Definition\ScalarType; use LongitudeOne\Spatial\PHP\Types\Geometry\Point; class PointType extends ScalarType { public $name = 'Point'; public $description = '地理坐标点,返回格式为 [经度, 纬度]'; // 序列化:将Point对象转为GraphQL可识别的输出格式 public function serialize($value) { if (!$value instanceof Point) { return null; } return [$value->getLongitude(), $value->getLatitude()]; } // 反序列化:处理客户端传入的参数转为Point对象,不需要写入可删除 public function parseValue($value) { if (!is_array($value) || count($value) !== 2) { throw new \InvalidArgumentException('Point参数必须为[经度, 纬度]格式的数组'); } return new Point($value[0], $value[1]); } // 处理GraphQL查询字面量,不需要写入可删除 public function parseLiteral($valueNode, ?array $variables = null) { if ($valueNode->kind !== 'ListValue' || count($valueNode->values) !== 2) { throw new \InvalidArgumentException('Point参数必须为[经度, 纬度]格式的数组'); } return new Point($valueNode->values[0]->value, $valueNode->values[1]->value); } }
- 第二步:修改API Platform配置,绑定类型映射
在config/packages/api_platform.yaml中添加如下配置:
api_platform: graphql: # 注册自定义标量 types: - App\GraphQL\Type\PointType # 将Doctrine的Point类型映射到自定义GraphQL标量 types_mapping: LongitudeOne\Spatial\PHP\Types\Geometry\Point: 'Point'
- 第三步:确认实体属性配置
确保coordinates属性加入了对应序列化组,无需修改原有类型注解:
#[ORM\Column(type: 'point')] #[Groups(['read:your_entity', 'write:your_entity'])] private ?Point $coordinates = null;
方案2:虚拟属性(仅需读取时更简单)
如果只需要返回坐标不需要写入,可直接在实体中新增虚拟序列化属性,无需额外配置:
// 原coordinates属性保持不变,移除对应的读取序列化组 #[ORM\Column(type: 'point')] #[Groups(['write:your_entity'])] private ?Point $coordinates = null; // 新增虚拟属性供GraphQL返回 #[Groups(['read:your_entity'])] #[GraphQLProperty(name: 'coordinates', type: '[Float!]!')] public function getSerializedCoordinates(): ?array { if (!$this->coordinates) { return null; } return [$this->coordinates->getLongitude(), $this->coordinates->getLatitude()]; }
配置完成后刷新缓存即可在GraphQL查询中正常获取coordinates字段返回值。
内容的提问来源于stack exchange,提问作者Vico-gs
相关产品推荐
相关产品推荐

