如何修改Prisma查询以匹配GraphQL订单创建Mutation的嵌套结构
解决订单创建Mutation返回order/orderItems为null的问题
以下是针对你遇到的问题的排查和解决步骤,结合Apollo Server、GraphQL、Prisma的协作逻辑逐一分析:
1. 检查DataSources中订单创建逻辑的返回值
你的orderAPI的createOrder方法必须创建后主动查询并返回包含关联数据的订单对象,不能只执行创建操作:
- 若你是分别创建payment、order、orderItems,最后必须用Prisma的
include选项查询完整的订单(包含orderItems) - 推荐用Prisma的嵌套创建(
orderItems: { create: [...] })+ 事务,确保数据一致性同时直接获取关联数据
示例修正后的orderAPI代码:
async createOrder(paymentData, orderData, orderItemsData) { return await this.prisma.$transaction(async (tx) => { // 1. 创建支付记录 const payment = await tx.payment.create({ data: paymentData }); // 2. 创建订单并同时创建关联的订单项,同时查询关联数据 const createdOrder = await tx.order.create({ data: { ...orderData, paymentId: payment.id, // 关联支付记录 orderItems: { create: orderItemsData // 嵌套创建订单项 } }, include: { orderItems: true, // 必须包含订单项,否则返回的order对象没有该字段 payment: true // 若需要返回支付信息也可包含 } }); return createdOrder; }); }
2. 确保Resolver返回结构与GraphQL Schema匹配
你的Mutation resolver必须返回与定义的响应类型完全匹配的结构,字段名和类型都要对应:
- 若你的Schema中
CreateOrderResponse包含order和orderItems字段,resolver需要从dataSources返回的对象中正确提取这两个值
示例修正后的Resolver代码:
const resolvers = { Mutation: { createOrder: async (_, { paymentData, orderData, orderItemsData }, { dataSources }) => { const createdOrder = await dataSources.orderAPI.createOrder(paymentData, orderData, orderItemsData); // 返回结构严格匹配Schema的CreateOrderResponse return { order: createdOrder, orderItems: createdOrder.orderItems, payment: createdOrder.payment // 若Schema包含该字段则返回 }; } } };
3. 验证GraphQL Schema的类型定义
确认你的Mutation响应类型和关联字段定义正确,避免因类型不匹配导致Apollo Server过滤字段:
# 确保响应类型包含非空的order和orderItems字段 type CreateOrderResponse { order: Order! # 非空类型,避免返回null orderItems: [OrderItem!]! # 非空数组类型 payment: Payment } type Order { id: ID! userId: ID! totalAmount: Float! orderItems: [OrderItem!]! # 订单与订单项的关联必须定义 } type OrderItem { id: ID! productId: ID! quantity: Int! price: Float! order: Order! # 订单项与订单的反向关联 }
4. 检查Prisma模型的关联配置
确保Prisma中Order、OrderItem、Payment的关联关系正确配置,否则无法查询到关联数据:
model Order { id String @id @default(cuid()) userId String totalAmount Float orderItems OrderItem[] // 订单到订单项的一对多关联 payment Payment? @relation(fields: [paymentId], references: [id]) paymentId String? } model OrderItem { id String @id @default(cuid()) orderId String productId String quantity Int price Float order Order @relation(fields: [orderId], references: [id], onDelete: Cascade) // 订单项到订单的多对一关联 } model Payment { id String @id @default(cuid()) orderId String @unique amount Float status String order Order @relation(fields: [orderId], references: [id], onDelete: Cascade) // 支付到订单的一对一关联 }
5. 调试技巧
- 在
orderAPI的createOrder方法末尾打印createdOrder,确认是否包含order和orderItems数据 - 在Resolver中打印
createdOrder,确认dataSources返回的数据是否正确 - 在Apollo Sandbox中查看查询的请求字段,确保你请求了
order和orderItems的具体子字段(比如order { id totalAmount },而不是只请求order字段本身)
内容的提问来源于stack exchange,提问作者CodeConnoisseur
相关产品推荐
相关产品推荐

