GraphQL响应中嵌套对象entity/funding的id字段返回null问题排查
问题:PostgreSQL to_json生成的嵌套对象id在GraphQL响应中返回null
我通过GraphQL查询获取所有账户数据,Resolver用关联多表的PostgreSQL语句获取数据,并用to_json生成entity和funding对象列。所有字段在数据库中都存在,但响应里account.id正常,account.entity.id和account.funding.id却返回null。单独查询entity.id和funding.id能得到正确值,GraphQL Schema中id定义为String类型。
响应示例:
"data": { "accounts": { "docs": [ { "name": "*******************", "slugName": "*************************", "id": "635********6d1", "entity": { "id": null, "slugName": "**************", "address": "0x****************************71C", "name": "*****************", "type": "*********" }, "funding": { "id": null, "slugName": "********************************", "type": "********", "name": "**********" } } ] } }
对应的SQL查询:
select account.*, to_json(entity.*) as "entity", to_json(funding.*) as "funding" from account left join entity on entity.id=account."entityId" left join funding on funding.id=account."fundingId"
原因分析
核心问题是PostgreSQL中entity.id/funding.id的数据类型与GraphQL Schema定义的String类型不兼容:
- 如果数据库中id是整数、UUID等非字符串类型,
to_json会将其序列化为对应原生类型(数字、UUID对象); - GraphQL的String标量无法解析这些非字符串类型,最终返回null;
- 单独查询id时,Resolver通常会自动完成类型转换,所以能正常返回值。
解决方案
方案1:在SQL中显式转换id为字符串
通过json_build_object手动构造JSON对象,将id强制转为text类型,确保to_json输出字符串格式的id:
select account.*, to_json(json_build_object( 'id', entity.id::text, 'slugName', entity."slugName", 'address', entity.address, 'name', entity.name, 'type', entity.type )) as "entity", to_json(json_build_object( 'id', funding.id::text, 'slugName', funding."slugName", 'type', funding.type, 'name', funding.name )) as "funding" from account left join entity on entity.id=account."entityId" left join funding on funding.id=account."fundingId"
方案2:在Resolver中转换id类型
在GraphQL Resolver获取数据库返回结果后,手动将嵌套对象的id转为字符串(以Node.js为例):
// 处理账户数据的逻辑 accounts.docs.forEach(account => { if (account.entity?.id) { account.entity.id = account.entity.id.toString(); } if (account.funding?.id) { account.funding.id = account.funding.id.toString(); } });
方案3:针对UUID类型的特殊处理
如果id是UUID类型,可直接用PostgreSQL的uuid_to_string函数转换:
to_json(json_build_object( 'id', uuid_to_string(entity.id), 'slugName', entity."slugName", 'address', entity.address, 'name', entity.name, 'type', entity.type )) as "entity"
验证方法
先在PostgreSQL客户端执行原SQL,查看返回的entity列中id的类型。如果是数字或UUID而非字符串,即可确认是类型不兼容导致的问题。
内容的提问来源于stack exchange,提问作者blockchaindevEY
相关产品推荐
相关产品推荐

