Вам необходимо решить, какая «форма» типа User имеет смысл для вашего клиентского приложения, независимо от того, что возвращается API REST.Для этого примера, скажем, мы используем:
type User {
id: String
mail: String
}
Кроме того, для примера рассмотрим, что у нас есть поле getUser
, которое возвращает одного пользователя.Любые аргументы не имеют отношения к сценарию, поэтому я здесь их опускаю.
type Query {
getUser: User
}
Если предположить, что я не знаю, какой API запрашивать у пользователя, наш распознаватель для getUser
может выглядеть примерно так:
async () => {
const [userFromA, userFromB] = await Promise.all([
fetchUserFromA(),
fetchUserFromB(),
])
// transform response
if (userFromA) {
const { id, communication: { mail } } = userFromA
return {
id,
mail,
}
}
// response from B is already in the correct "shape", so just return it
if (userFromB) {
return userFromB
}
}
В качестве альтернативы , мы можем использовать отдельные преобразователи поля для достижения того же эффекта.Например:
const resolvers = {
Query: {
getUser: async () => {
const [userFromA, userFromB] = await Promise.all([
fetchUserFromA(),
fetchUserFromB(),
])
return userFromA || userFromB
},
},
User: {
mail: (user) => {
if (user.communication) {
return user.communication.mail
}
return user.mail
}
},
}
Обратите внимание, что вам не нужно сопоставлять вашу схему с ответом от ваших существующих конечных точек REST.Например, может быть, вы захотите вернуть пользователя следующим образом:
type User {
id: String
details: UserDetails
}
type UserDetails {
email: String
}
В этом случае вам просто нужно преобразовать ответ из или API, чтобы он соответствовал вашей схеме.