Как вы записываете решатели запросов в GraphQL, которые хорошо работают с реляционной базой данных?Что такое идиоматический, эффективный способ решения связанных объектов?
Используя пример схемы от this tutorial, допустим, у меня простая база данных с users
и stories
. Пользователи могут создавать несколько историй, но в рассказах есть только один пользователь в качестве своего автора (для простоты).
При запросе для пользователя также может потребоваться список всех историй, созданных этим пользователем. Одно из возможных определений запроса GraphQL справиться с этим (украдено из приведенного выше связанного учебника):
const Query = new GraphQLObjectType({
name: 'Query',
fields:() => ({
user: {
type: User,
args: {
id: {
type: new GraphQLNonNull(GraphQLID)
}
},
resolve(parent, {id}, {db}) {
return db.get(`
SELECT * FROM User WHERE id = $id
`, {$id: id});
}
},
})
});
const User = new GraphQLObjectType({
name: 'User',
fields:() => ({
id: {
type: GraphQLID
},
name: {
type: GraphQLString
},
stories: {
type: new GraphQLList(Story),
resolve(parent, args, {db}) {
return db.all(`
SELECT * FROM Story WHERE author = $user
`, {$user: parent.id});
}
}
})
});
Это будет работать, как ожидалось; если я запрошу конкретного пользователя, я смогу также получить истории этого пользователя, если потребуется. Однако это не идеально. Это требует двух поездок в базу данных, когда одного запроса с JOIN
было бы достаточно. Проблема усиливается, если я запрашиваю несколько пользователей - каждый дополнительный пользователь приведет к дополнительному запросу базы данных. Проблема ухудшается экспоненциально, чем глубже пересекаю мои объектные отношения.
Решена ли эта проблема? Есть ли способ написать запрос-преобразователь, который не приведет к генерированию неэффективных SQL-запросов?
А, я заметил, что перед этим параметром 'fieldASTs', но теперь становится намного больше смысла, когда я вижу конкретный вариант использования. Благодаря! – ean5533