Làm cách nào để bạn viết các giải pháp truy vấn trong GraphQL hoạt động tốt với cơ sở dữ liệu quan hệ?Cách thành ngữ, biểu diễn để giải quyết các đối tượng liên quan là gì?
Sử dụng lược đồ ví dụ từ this tutorial, giả sử tôi có cơ sở dữ liệu đơn giản với users
và stories
. Người dùng có thể tác giả nhiều câu chuyện nhưng câu chuyện chỉ có một người dùng làm tác giả của họ (để đơn giản).
Khi truy vấn người dùng, người dùng cũng có thể muốn nhận danh sách tất cả các câu chuyện do người dùng đó tạo. Một định nghĩa có thể là truy vấn GraphQL để xử lý (bị đánh cắp từ hướng dẫn được liên kết ở trên):
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});
}
}
})
});
Điều này sẽ hoạt động như mong đợi; nếu tôi truy vấn một người dùng cụ thể, tôi cũng sẽ có thể nhận được câu chuyện của người dùng đó nếu cần. Tuy nhiên, điều này không thực hiện lý tưởng. Nó đòi hỏi hai chuyến đi đến cơ sở dữ liệu, khi một truy vấn đơn lẻ với JOIN
sẽ có đủ điều kiện. Vấn đề được khuếch đại nếu tôi truy vấn nhiều người dùng - mỗi người dùng bổ sung sẽ dẫn đến truy vấn cơ sở dữ liệu bổ sung. Vấn đề trở nên tồi tệ hơn theo cấp số nhân sâu hơn tôi đi qua các mối quan hệ đối tượng của tôi.
Sự cố này đã được giải quyết chưa? Có cách nào để viết một trình phân giải truy vấn không dẫn đến các truy vấn SQL không hiệu quả được tạo ra không?
Ah, tôi nhận thấy thông số 'fieldASTs' trước đây nhưng bây giờ nó có ý nghĩa hơn nhiều khi tôi thấy trường hợp sử dụng cụ thể. Cảm ơn! – ean5533