TanStack Query (React Query): Handling HTTP Requests with EaseEntry 9 of 10

Organizing Queries and Services

Conventions that keep query keys, fetch functions, and components maintainable as the app grows.

Notes

ConcernRecommendation
HTTPPlain fetch functions in services/, throwing on error
Query clientOne instance in util/query-client.ts
Query keysConsistent hierarchy: ['events'], ['events', { search }], ['events', id]
ReuseWrap repeated useQuery calls in custom hooks (useEvent(id))
DefaultsSet app-wide staleTime in QueryClient
WritesAlways useMutation, never useQuery
After writesInvalidate by prefix (['events'])
DebuggingReact Query Devtools

Code compare

React
// hooks/useEvent.ts — reusable query hookexport function useEvent(id: string) {  return useQuery({    queryKey: ["events", id],    queryFn: ({ signal }) => fetchEvent({ id, signal }),    staleTime: 60 * 1000,  });}
React
src/├── util/│   └── query-client.ts├── services/│   └── events.ts          // fetchEvents, fetchEvent, createNewEvent, updateEvent, deleteEvent├── hooks/│   └── useEvent.ts├── components/│   ├── NewEventsSection.tsx│   └── FindEventSection.tsx└── pages/    ├── NewEvent.tsx       // useMutation + invalidate    ├── EventDetails.tsx   // useQuery + delete mutation    └── EditEvent.tsx      // optimistic update
Angular
src/app/├── services/│   ├── events.service.ts        // HttpClient calls + version signal│   └── events-cache.service.ts  // optional staleTime cache├── events/│   ├── new-events-section.component.ts   // rxResource│   ├── find-event-section.component.ts   // rxResource with params│   ├── event-details.component.ts        // rxResource + optimistic update│   └── new-event.component.ts            // service call + invalidate└── app.config.ts                         // provideHttpClient()