You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 21:36:04