Apollo GraphQL:联合类型OrderType查询报错,如何正确查询字段?
GraphQL联合类型查询错误的解决方案
问题原因
GraphQL的联合类型(Union)本身不包含任何字段,它只是多个类型的集合。你不能直接在联合类型上查询子类型的字段——这是GraphQL的规范要求,目的是确保查询的类型安全性,避免误访问不存在的字段。
标准解决方案:使用内联片段
必须通过**内联片段(inline fragment)**指定具体的子类型,才能查询对应类型的字段。修改你的前端查询如下:
export const GET_ORDER_TYPE = gql` query getOrderType($userId: String!) { getOrderType(userId: $userId) { # 针对DeliveryType的字段 ... on DeliveryType { delivery deliveryStreetNumberId pickupLocationId storeId } # 针对PickupType的字段 ... on PickupType { storeId } } } `;
当服务器返回DeliveryType时,只会返回片段中定义的对应字段;返回PickupType时同理,不存在的字段不会出现在响应中。
其他可选处理方式
如果你希望更贴近“所有字段返回,不存在的为null”的需求,可以考虑以下两种方案:
1. 使用接口(Interface)替代联合类型
如果你的两个子类型有公共字段(比如storeId),可以定义一个接口让它们实现,这样可以先查询公共字段,再通过片段查询子类型的独有字段:
修改后的Schema:
interface OrderInterface { storeId: String! } type DeliveryType implements OrderInterface { delivery: String! deliveryStreetNumberId: String! pickupLocationId: String! storeId: String! } type PickupType implements OrderInterface { storeId: String! } type Query { getOrderType(userId: String!): OrderInterface }
对应的查询:
export const GET_ORDER_TYPE = gql` query getOrderType($userId: String!) { getOrderType(userId: $userId) { storeId # 公共字段直接查询 ... on DeliveryType { delivery deliveryStreetNumberId pickupLocationId } } } `;
2. 合并为单个带nullable字段的类型
如果你可以调整Schema,把联合类型改成一个包含所有可能字段的单个类型,用nullable字段表示可选性,同时增加一个类型标识字段:
修改后的Schema:
type OrderType { orderType: String! # 例如"DELIVERY"或"PICKUP",用于前端判断类型 delivery: String deliveryStreetNumberId: String pickupLocationId: String storeId: String! } type Query { getOrderType(userId: String!): OrderType }
对应的查询:
export const GET_ORDER_TYPE = gql` query getOrderType($userId: String!) { getOrderType(userId: $userId) { orderType delivery deliveryStreetNumberId pickupLocationId storeId } } `;
这种方式下,不存在的字段会返回null,但会失去GraphQL的类型安全校验,需要你在前端业务逻辑中自行判断orderType并处理不同字段。
内容的提问来源于stack exchange,提问作者Miha Šušteršič
相关产品推荐
相关产品推荐

