使用AWS Amplify AppSync创建Transplant时子类型Variety返回null报错的问题
嘿,这个报错我之前在处理Amplify关联的时候也碰到过,咱们一步步拆解解决:
首先看核心错误信息:Cannot return null for non-nullable type: 'ID' within parent 'Variety' (/createTransplant/variety/id),翻译过来就是:你在查询createTransplant返回结果的variety.id时,这个id是必填字段,但实际返回了null,所以触发了GraphQL的非空校验报错。
先排查最可能的根源:关联ID无效
看你的mutation里,transplantPlantId、transplantPlantingBedId、transplantVarietyId用了完全相同的ID,这肯定有问题啊!Plant、PlantingBed、Variety是三个独立的模型,它们的记录ID不可能一模一样,大概率是你复制粘贴的时候偷懒了,导致transplantVarietyId对应的Variety记录根本不存在。
你可以先跑个查询验证一下这个ID对应的Variety是否存在:
query CheckVarietyExists { getVariety(id: "d108d-a6f3-024e-c281-5affed45fb1") { id name } }
如果这个查询返回null,那就是ID的问题,换成真实存在的Variety记录ID就好。
如果Variety确实是可选关联(不需要每次都传)
你的Transplant模型里variety: Variety @hasOne是可选的(没有加!),这意味着创建Transplant时可以不关联Variety。但这时候要注意:如果没传transplantVarietyId或者传的ID无效,variety字段会返回null,这时候你在mutation的返回字段里请求variety.id,就像从空盒子里拿东西,肯定报错。
解决这个场景的两种办法:
- 按需请求嵌套字段:只有当你确定要关联有效Variety时,才在返回结果里请求
variety的嵌套字段;如果不需要关联,就把variety相关的返回字段删掉。 - 用条件指令动态控制:借助GraphQL的
@include指令,只有当传入了有效Variety ID时才请求variety字段:
调用时如果要关联Variety就传mutation MyMutation($varietyId: ID, $input: CreateTransplantInput!) { createTransplant(input: $input) { id date plant { name } numberOfSeedlings # 只有当$varietyId存在时才请求variety字段 variety @include(if: $varietyId) { id name } } }$varietyId,不需要就留空,这样就不会触发null报错了。
额外小优化:合并重复的查询字段
你的mutation里重复写了两次variety字段,虽然不影响功能,但属于冗余代码,合并成一次更整洁:
mutation MyMutation { createTransplant(input: { numberOfSeedlings: 22, transplantPlantId: "真实的PlantID", transplantPlantingBedId: "真实的PlantingBedID", transplantVarietyId: "真实的VarietyID", date: "2024-07-20T00:00:00.000Z" }) { id date plant { name } numberOfSeedlings variety { id name plant } } }
最后检查模型关联配置
如果上面的方法都没用,再确认下Variety模型的定义,确保它有ID!类型的id字段,并且和Transplant的关联配置正确(Amplify的@hasOne会自动生成关联字段,一般不会出问题,但可以去Amplify控制台的DataStore里看模型结构)。
备注:内容来源于stack exchange,提问作者bernieslearnings

