GitHub

API Integration

Typed REST and GraphQL clients with interceptors, retry logic, and centralized error handling using React Query.

01

Principle

All API calls flow through a single typed client layer. React Query wraps the client for caching and synchronization. Components never call fetch() directly — they use custom hooks that compose the query client and API client together.

lightbulb

Use Zod to validate API responses at the boundary. This catches backend contract violations early and ensures your types are always accurate.

02

Rules

  • check_circle
    Single API Client InstanceOne Axios/fetch instance with all interceptors. Import it everywhere via a singleton.
  • check_circle
    Type All ResponsesDefine TypeScript interfaces for every endpoint. Use Zod for runtime validation.
  • check_circle
    Centralized Error HandlingMap API error codes to user-friendly messages in one place — not scattered in components.
  • check_circle
    Retry Transient FailuresConfigure React Query retry logic for 5xx errors. Never retry 4xx client errors.
03

Pattern

lib/api-client.ts
import axios from 'axios';
import { z } from 'zod';

const apiClient = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_URL });

export async function fetchTyped<T>(
  url: string,
  schema: z.ZodType<T>,
): Promise<T> {
  const { data } = await apiClient.get(url);
  return schema.parse(data);
}
04

Implementation

info

Version Compatibility

Requires React 19+ and the latest stable versions of all dependencies shown.

In Next.js, use Route Handlers as a BFF (Backend for Frontend) layer to proxy external APIs and add auth headers server-side.

app/api/posts/route.ts
import { NextResponse } from 'next/server';
import { postListSchema } from '@/lib/schemas';

export async function GET() {
  const res = await fetch(process.env.EXTERNAL_API + '/posts', {
    headers: { Authorization: `Bearer ${process.env.API_SECRET}` },
    next: { revalidate: 60 },
  });
  const data = postListSchema.parse(await res.json());
  return NextResponse.json(data);
}
menu_book
React Patterns

Helping developers build robust React applications since 2025.

© 2025 React Patterns Cookbook. Built with ❤️ for the community.
react-principles