Wie schreiben Sie Abfrage-Resolver in GraphQL, die sich gut gegen eine relationale Datenbank eignen?Was ist der idiomatische, performante Weg, um verwandte Objekte zu lösen?
Verwenden Sie das Beispielschema von this tutorial, sagen wir, ich habe eine einfache Datenbank mit users
und stories
. Benutzer können mehrere Stories erstellen, aber Stories haben nur einen Benutzer als Autor (zur Vereinfachung).
Wenn man nach einem Benutzer fragt, möchte man vielleicht auch eine Liste aller Geschichten erhalten, die von diesem Benutzer verfasst wurden. Eine mögliche Definition eine GraphQL Abfrage, damit umzugehen (gestohlen aus der oben verlinkten Tutorial):
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});
}
}
})
});
Dies wird wie erwartet; Wenn ich einen bestimmten Benutzer abfrage, kann ich bei Bedarf auch die Storys dieses Benutzers abrufen. Dies funktioniert jedoch nicht optimal. Es erfordert zwei Fahrten zur Datenbank, wenn eine einzige Abfrage mit JOIN
genügt hätte. Das Problem wird verstärkt, wenn ich mehrere Benutzer abfrage - jeder weitere Benutzer führt zu einer zusätzlichen Datenbankabfrage. Das Problem wird umso schlimmer, je tiefer ich meine Objektbeziehungen durchlaufe.
Wurde dieses Problem gelöst? Gibt es eine Möglichkeit, einen Abfrage-Resolver zu schreiben, der nicht dazu führt, dass ineffiziente SQL-Abfragen generiert werden?
Ah, ich habe das Feld "fieldASts" vorher bemerkt, aber es macht jetzt viel mehr Sinn, wenn ich einen konkreten Anwendungsfall sehe. Vielen Dank! – ean5533