İçeriğe geç
Zeynep Baş — Ana sayfa
Tüm yazılar
  • React Query
  • Repository Pattern
  • Mimari

React Query ile Repository Pattern’i Birlikte Kullanmak

Veri erişimini repository katmanında soyutlayıp, cache ve senkronizasyonu React Query’ye bırakarak bileşenleri sade, test edilebilir ve backend değişikliklerine dayanıklı hale getirmek.

Zeynep Baş9 dk okuma

Problem: bileşenlere dağılmış veri mantığı

Projeler büyüdükçe fetch çağrıları, URL’ler, response dönüşümleri ve hata yönetimi bileşenlerin içine dağılır. Aynı endpoint farklı ekranlarda farklı şekilde çağrılır; backend’deki küçük bir değişiklik onlarca dosyaya dokunmayı gerektirir.

React Query cache, yeniden deneme ve senkronizasyonu harika çözer; ama verinin nereden ve nasıl geldiği sorusunu çözmez. Repository pattern tam da bu boşluğu doldurur.

Repository katmanı

Repository, veri kaynağına erişimi tek bir arayüzün arkasına saklar. Bileşen “ürünleri getir” der; REST mi, GraphQL mi, mock mu olduğunu bilmez.

features/products/api/product.repository.tsTypeScript
export interface ProductRepository {
  getAll(params?: ProductQuery): Promise<Product[]>;
  getById(id: string): Promise<Product>;
  update(id: string, dto: UpdateProductDto): Promise<Product>;
}

export const productRepository: ProductRepository = {
  async getAll(params) {
    const { data } = await http.get('/products', { params });
    return data.map(toProduct); // adapter
  },
  async getById(id) {
    const { data } = await http.get(`/products/${id}`);
    return toProduct(data);
  },
  async update(id, dto) {
    const { data } = await http.patch(`/products/${id}`, dto);
    return toProduct(data);
  },
};

Query key fabrikası

Cache anahtarlarını dağınık string’ler yerine tek bir fabrikada toplamak, invalidation işlemlerini öngörülebilir kılar.

features/products/api/product.keys.tsTypeScript
export const productKeys = {
  all: ['products'] as const,
  list: (q?: ProductQuery) => [...productKeys.all, 'list', q] as const,
  detail: (id: string) => [...productKeys.all, 'detail', id] as const,
};

React Query ile birleştirmek

Custom hook’lar repository’yi React Query’ye bağlar. Bileşen artık sadece hook’u çağırır; veri erişimi ve cache stratejisi tek yerde yaşar.

features/products/hooks/useProducts.tsTypeScript
export function useProducts(q?: ProductQuery) {
  return useQuery({
    queryKey: productKeys.list(q),
    queryFn: () => productRepository.getAll(q),
    staleTime: 60_000,
  });
}

export function useUpdateProduct() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ id, dto }: { id: string; dto: UpdateProductDto }) =>
      productRepository.update(id, dto),
    onSuccess: (p) => {
      qc.setQueryData(productKeys.detail(p.id), p);
      qc.invalidateQueries({ queryKey: productKeys.all });
    },
  });
}

Sonuç

Repository veri erişimini, React Query sunucu durumunu, custom hook’lar ikisini birbirine bağlar. Sonuç: test edilebilir, backend değişikliklerine dayanıklı ve bileşenleri sade tutan bir API katmanı.

Diğer yazılar