HTTP Clients TypeScript 2024
Fetch API (natywny), Axios (interceptory), ky (2KB, hooks), ofetch (universal) i TanStack Query (caching + sync).
6 HTTP clients — bundle size i zastosowanie
Fetch, Axios, ky, ofetch, TanStack Query i SWR — bundle size i kiedy wybrać.
| Klient | Bundle | Kiedy |
|---|---|---|
| Fetch API | 0KB (natywny) | Node.js 18+, brak zależności, streaming, modern |
| Axios | 14KB (gzip: 5KB) | Interceptory, legacy Node.js, transform, formData |
| ky | 2KB (ESM) | Browser-focused, hooks, retry wbudowany, modern |
| ofetch | 3KB | SSR/Nuxt, universal, auto-parse, onResponse hooks |
| TanStack Query | 24KB | React + caching + sync server state, SWR-like |
| SWR (Vercel) | 8KB | React, proste, Next.js integration, lightweight |
Często zadawane pytania
Fetch API — nowoczesne zapytania HTTP w TypeScript?
Fetch API: natywny browser + Node.js 18+. Zero dependencies. Standard W3C. Podstawy TypeScript: const response = await fetch('https://api.example.com/users'). if (!response.ok) throw new Error('HTTP error ' + response.status). const data = await response.json() as User[]. Type safety: response.json() zwraca Promise any. Cast: as User[]. Lub Zod parse: const users = UserArraySchema.parse(await response.json()). POST z body: await fetch('/api/users', {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({name, email})}). AbortController: const controller = new AbortController(). fetch(url, {signal: controller.signal}). controller.abort(). Timeout: const timeout = setTimeout(() => controller.abort(), 5000). Obsługa błędów: sieciowe (throw) vs HTTP errors (response.ok). Zawsze sprawdź response.ok. Streaming: response.body — ReadableStream. for await (const chunk of response.body) { ... }. Przydatne dla dużych plików. SSE: EventSource lub fetch streaming. Cookies: credentials: 'include'. CORS z cookies. same-origin dla same-domain. Node.js 18+: undici pod spodem. fetch globalny. Brak polyfill. Starsze: node-fetch biblioteka. Request/Response cache: cache option. Next.js rozszerza fetch. cache: 'no-store' lub 'force-cache'. Zapis do cache. revalidate.
Axios — features, interceptory i TypeScript generics?
Axios: najpopularniejszy HTTP client. Interceptory. Request/response transform. Browser + Node.js. Automatyczny JSON. Instalacja: npm install axios. TypeScript generics: const {data} = await axios.get('/api/users'). Typowane automatycznie. Lub axios.get('/api/user'). data jest User. Instancja: const api = axios.create({baseURL: 'https://api.example.com', timeout: 10000, headers: {'Authorization': 'Bearer ' + token}}). Interceptory: api.interceptors.request.use((config) => { config.headers.Authorization = getToken(). return config }). Response interceptor: api.interceptors.response.use(null, (error) => { if (error.response?.status === 401) redirect('/login'). return Promise.reject(error) }). Error handling: axios.isAxiosError(error). error.response — serwer odpowiedział. error.request — brak odpowiedzi. error.message — setup error. AxiosError typed. Cancel request: AbortController (nowe). Lub CancelToken (deprecated). axios.isCancel(error). Progress: onUploadProgress, onDownloadProgress. File upload. CSRF: xsrfHeaderName, xsrfCookieName. Automatyczne. FormData: axios.post(url, formData). Automatyczny Content-Type. Upload pliku. Retry: axios-retry biblioteka. axiosRetry(axios, {retries: 3}). Exponential backoff. Custom retry condition. Porównanie z fetch: Axios — interceptors, transforms, Node <18. Fetch — natywny, mniejszy bundle, streaming lepszy. Trend: fetch rośnie (Node 18+). Axios nadal popular dla interceptors.
ky i ofetch — nowoczesne fetch wrappery?
ky: nowoczesny fetch wrapper. Sindre Sorhus. ESM only. Mały (2KB). API podobny do fetch. Instalacja: npm install ky. Podstawy: import ky from 'ky'. const data = await ky.get('https://api.example.com/users').json(). Lub: const data = await ky('/api/users', {method: 'GET'}).json(). Auto-retry: const data = await ky.get(url, {retry: {limit: 3, methods: ['get'], statusCodes: [429, 503]}, hooks: {beforeRetry: [async ({error, retryCount}) => { console.log('retry', retryCount) }]}}).json(). Timeout: timeout: 10000. Hooks: beforeRequest, beforeRetry, beforeError, afterResponse. Zamiast interceptorów. Errors: HTTPError (response, request). error.response dostępny. Prefixing: ky.extend({prefixUrl: 'https://api.example.com', headers: {Authorization: 'Bearer ' + token}}). Jak axios.create. JSON body: ky.post('/api/users', {json: {name: 'Jan'}}). Automatyczny Content-Type. ofetch: Nuxt team. Cross-platform. Auto-parse. TypeScript. npm install ofetch. Użycie: import {ofetch} from 'ofetch'. const data = await ofetch('/api/users'). Automatyczny JSON parse. Base URL: const api = ofetch.create({baseURL: 'https://api.example.com', headers: {Authorization: 'Bearer ' + token}}). onRequest, onResponse, onResponseError hooks. Error: FetchError. statusCode, data. Retry wbudowany. ofetch w Nuxt: $fetch (global). useFetch hook. SSR streaming. Który wybrać: ky — browser-focused, hooks. ofetch — SSR/Nuxt, universal. Axios — legacy, Node old versions, interceptors pattern.
TanStack Query jako HTTP client — pattern i konfiguracja?
TanStack Query: data fetching + caching. Nie HTTP client sam w sobie. Ale zarządza stanem zapytań. Używaj z fetch, axios lub ky. Pattern: const {data, isLoading, error} = useQuery({queryKey: ['users'], queryFn: () => fetch('/api/users').then(r => r.json())}). QueryClient konfiguracja: const queryClient = new QueryClient({defaultOptions: {queries: {staleTime: 1000 * 60 * 5, gcTime: 1000 * 60 * 30, retry: 3, retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000)}}}). prefetchQuery: queryClient.prefetchQuery({queryKey: ['users'], queryFn: fetchUsers}). SSR prefetch. Mutations: const mutation = useMutation({mutationFn: (newUser: User) => api.post('/users', {json: newUser}).json(), onSuccess: () => queryClient.invalidateQueries({queryKey: ['users']})}). optimisticUpdate. Global error handler: queryClient.setDefaultOptions({queries: {onError: (error) => toast.error('Błąd zapytania')}}). Suspense: useSuspenseQuery — rzuca Promise do Suspense. useQuery {enabled}: zapytanie warunkowe. enabled: !!userId. Dependent queries. Polling: refetchInterval: 5000. Pause when hidden. select: transformuj dane po fetch. select: (data) => data.filter(u => u.active). Memoizowane. Infinite queries: useInfiniteQuery. fetchNextPage. hasNextPage. Scroll to load more. Offline: networkMode: 'offlineFirst'. Paused queries. Retry gdy online.
HTTP client best practices — error handling, retry i type safety?
Centralny HTTP client: jeden plik api.ts lub http.ts. Konfiguracja baseURL, auth, interceptors. Importuj wszędzie. Brak scattered fetch calls. TypeScript wrapper: type ApiResponse T = {data: T. status: number. headers: Headers}. async function apiGet(url: string): Promise ApiResponse T. Typowany response. Zod validation: const UserSchema = z.object({id: z.string(), name: z.string(), email: z.string().email()}). const user = UserSchema.parse(await api.get('/users/' + id).json()). Runtime type check. Error classes: class HttpError extends Error { constructor(public status: number, public data: unknown, message: string) { super(message) } }. class NetworkError extends Error. class TimeoutError extends Error. instanceof check. Error hierarchy. Retry z exponential backoff: function retry(fn: () => Promise T, retries = 3): Promise T. for (let i = 0; i... try { return await fn() } catch (e) { if (i === retries - 1) throw e. await sleep(1000 * 2 ** i) } }. Timeouts: AbortController + setTimeout. Lub ky timeout option. 30 sekund max. Krótszy dla crítico. Request deduplication: TanStack Query robi to automatycznie. Lub własna Map pending requests. Nie rób 2x tego samego request. Auth: Bearer token w interceptorze/hook. Refresh token flow. 401 -> refresh -> retry. nie duplicate refresh requests. Semaphore pattern. Monitoring: axios instance z duration measure. fetch duration tracking. Error reporting do Sentry. Slow requests alert. Environment: process.env.NEXT_PUBLIC_API_URL. Type-safe env z @t3-oss/env-nextjs. Validation przy starcie.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz