GraphQL N+1 Sorunu: Sorguları Optimize Etmek

Bir GraphQL sorgusunda, ilişkili verileri çekerken her kayıt için ayrı bir veritabanı sorgusu çalıştırılmasıdır. Örneğin 100 yazarın bulunduğu bir listede her yazarın kitaplarını çekmek için 1 sorgu yazarlar için, 100 sorgu da kitaplar için toplam 101 sorgu demektir. Bu performansı ciddi şekilde düşürür.

GraphQL resolver'ları varsayılan olarak bağımsız çalışır. Bir alan resolve edilirken, ilişkili veriler için ayrı ayrı veri kaynağına erişilir. Batch işleme mekanizması olmadan her çağrı yeni bir sorguya dönüşür.

DataLoader, sorguları toplar ve tek seferde işler. Node.js ortamında en yaygın kütüphanedir.

Adım 1: Kurulum

1npm install dataloader

Adım 2: DataLoader Oluşturma

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1const DataLoader = require('dataloader');
2
3const bookLoader = new DataLoader(async (authorIds) => {
4const books = await db.query(
5'SELECT * FROM books WHERE author_id = ANY($1)',
6[authorIds]
7);
8return authorIds.map(id => books.filter(b => b.author_id === id));
9});

Adım 3: Resolver'da Kullanma

1const resolvers = {
2Author: {
3books: (author, _, { loaders }) => {
4return loaders.bookLoader.load(author.id);
5}
6}
7};

Adım 4: Context'e Loaders Ekleme

1const server = new ApolloServer({
2typeDefs,
3resolvers,
4context: () => ({
5loaders: { bookLoader }
6})
7});
8[/cod]
9
10**Beklenen Çıktı:**
11
12Aynı sorgu 101 yerine 2 sorguda tamamlanır: 1 yazarlar, 1 tüm kitaplar.
13
14Eğer DataLoader kullanamıyorsan, resolver'da manuel batch yapabilirsin:
15
16[kod]
17const resolvers = {
18Author: {
19books: async (author, _, { db }) => {
20const books = await db.query(
21'SELECT * FROM books WHERE author_id = $1',
22[author.id]
23);
24return books;
25}
26}
27};

Bu yöntem N+1 sorununu çözmez, ama cache mekanizması ekleyerek iyileştirebilirsin.

DataLoader en etkili çözümdür. Sorguları toplar, birleştirir ve veritabanı yükünü önemli ölçüde azaltır. Büyük ölçekli uygulamalarda neredeyse zorunludur.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz