- 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.
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.
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.
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ı.