繁体   English   中英

GraphQL可以选择解析在解析器中给定查询结果的字段吗?

[英]Can GraphQL optionally resolve a field given result of a query in resolver?

我有以下REST端点:

/命令/ {ID}

returns {
    orderId,
    orderItem,
    customerId
}

/客户/ {ID}

returns {
   customerId,
   firstName,
   lastName
}

我被这两个端点限制,这两个端点将包含在我的graphql模式中。

我想要以下架构:

type Order {
  orderId: ID!,
  orderItem: String,
  customer: Customer
}

type Customer{
  customerId: ID!
  firstName: String!
  lastName: String!
}

type Query {
  getOrder(id: String!): Order,
  getCustomer(id: String!): Customer
}

我想知道是否有可能让GraphQL解析Order类型中的Customer对象? 我知道你不能将查询结果传递给另一个参数。

我认为getOrder的解析器是:

const getOrderResolver = axios.get(`/orders/${id}`)
  .then((ordersRes) => {
    let customerId;
    if(ordersRes.data.customerId !== null) {
      customerId = ordersRes.data.customerId 
      axios.get(`/customers/${customerId}`)
      .then((customerRes) => ({
        return {
          orderId: ordersRes.data.orderId
          orderItem: ordersRes.data.orderItem
          customer: {
            customerId: customerRes.data.customerId
            firstName: customerRes.data.firstName
            lastName: customerRes.data.lastName 
          }
        }
      })
    } else {
      return {
          orderId: ordersRes.data.orderId
          orderItem: ordersRes.data.orderItem
          customer: null
      }
    }
    })
  })

getCustomer解析器

const getCustomerResolver = axios.get(`/customers/${customerId}`)
          .then((customerRes) => ({
            return {
                customerId: customerRes.data.customerId
                firstName: customerRes.data.firstName
                lastName: customerRes.data.lastName 
            }
          })

在我的解决方案中,无论是否在getOrder查询中查询,总是会获取Customer类型的额外成本。 是否有可能以GraphQL只能在查询时才能解析Customer类型的方式重写我的GraphQL架构?

我给定的ORDERS REST API的限制仅返回CustomerId使得难以在getOrder解析,因为Customer API需要customerId

这里要记住两件事:

  • GraphQL不会解析字段,除非它被请求(即除非字段实际包含在请求中,否则不会调用您的解析器)。
  • 每个解析器都可以访问其“父”字段解析为的值。

所以你的getOrder解析器只能担心返回一个订单对象:

const resolvers = {
  Query: {
    getOrder: (parent, args, context, info) => {
      const response = await axios.get(`/orders/${args.id}`)
      return response.data
    },
    ...
  },
  ...
}

请注意,如果REST端点以与字段类型相同的“形状”返回响应,则无需在此处将响应数据映射到实际字段 - 只需返回response.data

现在我们可以在订单类型上为customer字段添加解析器:

const resolvers = {
  Query: { ... },
  Order: {
    customer: (parent, args, context, info) => {
      if (!parent.customerId) {
        return null
      }
      const response = await axios.get('/customers/${parent.customerId}')
      return response.data
    },
  },
  ...
}

这里的父字段将是getOrder (或具有Order类型的任何其他字段)。 parent的值将是你在该字段的解析器中返回的任何值(或者如果你返回了Promise,无论Promise解决了什么)。 因此,我们可以使用parent.customerId来调用/customers端点并从响应中返回数据。 同样,只有在实际请求customer字段时才会调用此解析程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM