Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

GraphQL API isteklerinin response'larını Apollo Client cache'inde nasıl yapılandırarak gereksiz network isteklerini kestim

thedevx

Üye
Katılım
14 Mart 2026
Mesajlar
10
Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorunu ve nasıl çözdüğümü anlatacağım. Bir React/Next.js projesinde Apollo Client kullanıyordum ve her sayfa değişiminde, her component mount olduğunda aynı GraphQL sorgularının tekrar tekrar sunucuya gittiğini fark ettim. Bu durum hem kullanıcı deneyimini yavaşlatıyor hem de sunucuya gereksiz yük bindiriyordu. İşte benim kullandığım en temiz çözüm: Apollo Client cache yapılandırmasını doğru bir şekilde yapmak.

🔥 Karşılaştığım Sorun ve Cache'in Önemi

Apollo Client varsayılan olarak harika bir cache mekanizması sunar, ancak onu doğru yapılandırmazsanız potansiyelini kullanamazsınız. Benim sorunum, `fetchPolicy` ve `nextFetchPolicy` gibi ayarları hiç kullanmamamdı. Her sorgu, cache'te aynı veri olsa bile, network'e gidip "Ben buradayım, bana yeni data ver!" diye bağırıyordu. Bu, özellikle kullanıcı profil bilgileri veya sabit site ayarları gibi sık sorgulanan ama nadiren değişen verilerde çok can sıkıcıydı.

⚙️ Apollo Client Kurulumumu ve Cache Politikamı Nasıl Yapılandırdım?

İlk adım, Apollo Client instance'ımı oluştururken default fetch politikalarını belirlemek oldu. Ana `InMemoryCache` ve `ApolloClient` yapılandırmamı şu şekilde güncelledim:

JavaScript:
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';

const httpLink = createHttpLink({
  uri: 'https://api.orneksitem.com/graphql',
});

const authLink = setContext((_, { headers }) => {
  // ... token logic
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    }
  };
});

const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        // Burada spesifik alanlar için cache politikası yazabilirsiniz
        posts: {
          keyArgs: false, // Args farklı olsa bile aynı cache'i kullan (sayfalama için önemli!)
          merge(existing = [], incoming) {
            return [...existing, ...incoming];
          },
        }
      }
    }
  }
});

export const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: cache,
  defaultOptions: {
    watchQuery: {
      fetchPolicy: 'cache-first',
      nextFetchPolicy: 'cache-first',
    },
    query: {
      fetchPolicy: 'cache-first',
      nextFetchPolicy: 'cache-first',
    },
  },
});

Bu yapılandırmadaki sihirli nokta, `defaultOptions` kısmı. Burada tüm sorgular için varsayılan politikayı `'cache-first'` yapıyorum. Yani Apollo, bir sorgu yapıldığında önce cache'ine bakar, eğer cevap orada varsa network'e hiç gitmez. `nextFetchPolicy` ise ilk sorgudan sonraki sorgular için geçerli olan politikayı belirler. Bu ikili, gereksiz istekleri kesmek için birebir.

🎯 Sorgu Bazında İnce Ayar: fetchPolicy Kullanımı

Tabii ki her sorgu aynı değil. Bazı veriler gerçek zamanlı olmalı (örneğin anlık mesajlaşma), bazıları ise cache'te kalabilir. Bu nedenle, component seviyesinde `fetchPolicy` belirleyerek default ayarı geçersiz kılabilirsiniz. İşte iki farklı senaryo:

JavaScript:
// SENARYO 1: SADECE İLK SEFER NETWORK, SONRASI CACHE (Site Ayarları)
import { gql, useQuery } from '@apollo/client';

const GET_SITE_SETTINGS = gql`
  query GetSiteSettings {
    siteSettings {
      title
      logoUrl
      theme
    }
  }
`;

function Header() {
  const { data } = useQuery(GET_SITE_SETTINGS, {
    fetchPolicy: 'cache-and-network', // İlk yüklemede hem cache'i göster hem network'ten tazele
    nextFetchPolicy: 'cache-first', // Sonraki yüklemelerde sadece cache'e bak
  });
  // ... component logic
}

JavaScript:
// SENARYO 2: HER ZAMAN TAZE DATA (Canlı Borsa Verisi)
const GET_LIVE_STOCK = gql`
  query GetLiveStock($symbol: String!) {
    liveStock(symbol: $symbol) {
      price
      change
    }
  }
`;

function StockTicker({ symbol }) {
  const { data } = useQuery(GET_LIVE_STOCK, {
    variables: { symbol },
    fetchPolicy: 'network-only', // Cache'i umursama, her zaman network'ten al
    pollInterval: 10000, // Hatta her 10 saniyede bir otomatik yenile
  });
  // ... component logic
}

Gördüğünüz gibi, `'cache-and-network'` ve `'network-only'` gibi politikalarla ince ayar yapmak mümkün. Kritik nokta, hangi sorgunun ne sıklıkla değiştiğini analiz edip buna uygun politika seçmek.

💡 Cache'i Manuel Yönetmek ve Performans İpuçları

Bazen cache'i manuel olarak güncellemek veya temizlemek gerekebilir. Örneğin, kullanıcı çıkış yaptığında cache'i temizlemek iyi bir pratiktir. Ya da bir mutation (örneğin yeni yorum ekleme) sonrası, ilgili sorgunun cache'ini güncellemek gerekir.

JavaScript:
// Cache'i tamamen temizleme
import { client } from './apolloClient';
const handleLogout = async () => {
  await client.clearStore();
};

// Mutation sonrası cache'i güncelleme (Optimistic UI için)
const [addComment] = useMutation(ADD_COMMENT_MUTATION, {
  update(cache, { data: { addComment } }) {
    // Mevcut yorumlar sorgusunun cache'ini oku
    const existingComments = cache.readQuery({
      query: GET_COMMENTS,
      variables: { postId }
    });
    // Yeni yorumu ekleyerek cache'i yeniden yaz
    cache.writeQuery({
      query: GET_COMMENTS,
      variables: { postId },
      data: {
        comments: [addComment, ...existingComments.comments]
      }
    });
  },
  optimisticResponse: {
    // Kullanıcıya anında geri bildirim için
    addComment: {
      __typename: 'Comment',
      id: 'temp-id',
      body: inputValue,
      // ... diğer alanlar
    }
  }
});

Bu manuel müdahaleler, kullanıcı arayüzünün anında tepki vermesini sağlar ve network isteğinin tamamlanmasını beklemeden cache'i güncelleyerek harika bir kullanıcı deneyimi sunar.

Sonuç olarak, Apollo Client cache'ini doğru yapılandırmak, uygulamanın performansını gözle görülür şekilde artırıyor. Artık sayfalar arasında gezinirken eski sayfaya döndüğümde veriler anında yükleniyor ve sunucu istek sayım ciddi oranda azaldı.

Siz Apollo Client veya başka bir GraphQL istemcisi (Relay, URQL) kullanırken cache konusunda benzer sorunlar yaşadınız mı? Sizin kullandığınız farklı bir cache stratejisi veya performans ipucu var mı? Yorumlarda paylaşalım!
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri