Может ли GraphQL дополнительно разрешить поле с заданным результатом запроса в распознавателе? - PullRequest
7 голосов
/ 16 мая 2019

У меня есть следующие конечные точки 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 разрешил объект Customer в типе Order? Я понимаю, что вы не можете передать результат запроса в параметр другого.

Я считаю, что решатель 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 resolver

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

Похоже, с моим решением будет дополнительная плата за выборку типа Customer независимо от того, запрашивается он или нет в запросе getOrder. Можно ли переписать мою схему GraphQL таким образом, чтобы GraphQL мог разрешить тип Customer только при запросе?

Ограничение моего данного ORDERS REST API возвращает только CustomerId, затрудняет разрешение в getOrder, поскольку для Customer API требуется customerId

1 Ответ

2 голосов
/ 20 мая 2019

Здесь нужно помнить о двух вещах:

  • 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 будет любым значением, которое вы вернули в распознавателе этого поля (или, если вы вернули Обещание, независимо от того, к чему это Обещание разрешено).Таким образом, мы можем использовать parent.customerId для вызова конечной точки /customers и вернуть данные из ответа.И снова, этот распознаватель будет вызываться только в том случае, если поле customer действительно запрошено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...