#06: My favorite client side API stack
Hey! This week we take a look into my (currently) most favorite API client side stack. Axios as an API client and react-query as the "state" management hedgehog.
Hey, it’s Tomáš! I hope you enjoy this newsletter as much as I do! ♥️
If you have any tools, topics, library you would like to see featured, or just want to say hi, then consider joining my discord server, dm or mail directly.
Without further ado, let’s shoot straight into this weeks edition!
How would you implement client side REST API?
A question that sparked this edition and more editions to come when I was having a beer with friends last week. In this issue, we are going to take a look at my most favorite client side REST API stack implementation in React and Typescript.
Here is what’s in store today:
Axios - API client that (almost) everybody knows
react-query - powerful declarative caching enterprise level wrapper around API calls
Axios
99% of you probably know Axios, but I would describe it as the standard in current web dev when talking about API calls. It allows you to create a client instance where you define the API root with all of the necessary headers that you require to then simply reuse and create REST request just on the required endpoints.
Notable mention here is generic fetch
function in JS/TS which is great for single use scripts where you don’t want to bundle in any other unnecessary dependencies to reduce the size of the script. But I would personally not recommended this for large applications as it lacks the nice to have features which Axios has.
react-query
react-query + Axios is my go to stack for client side implementation of API fetching. It is beginner friendly and it allows you to completely ditch the global state which was the golden standard for some past years.
With react-query you create mutators (which do changes) and queries (which read data). You use and reuse these in combination with API request functions (can be fetch
, Axios, or any other API client) which you define. It supports a fully fledged cache system with tag invalidation and pagination, suspense, query cancellation, optimistic updates, …
How do you replace the global state?
When you do a classic query with fetch
you just take the data, push them through some logic, store them somewhere and maintain the state for next request, refresh… All this work to just work with an API and probably stored in redux and in a better case fetched with rtk-query which I controversially consider bloatware in new projects.
This creates unnecessary spaghetti code and the old looking JS-like typescript, promise nesting, etc… Nobody want’s this (Note: rtk-query is fine if you are stuck with redux in an old project)
This package brings cache into play, where you can define custom hooks to reuse the queries/mutators, which return the desired data from cache or fetch them if they are not in the cache. Then if you want to update the data, you create mutator, which invalidates the cache. If you use the query hook in 100 places then only one request is made and the data is then distributed among all of the hook calls.
Give me the code already!
Using this approach you can completely build your app state management on react-query relying on cache, cache invalidation and on optimistic updates.
Note: react-query V4 enables by default tracked queries. This will result for
useUser
in notifying us when any of the fieldsdata
,isLoading
,isError
change
Did you like this weeks edition?
Do you want me to do this kind of write up style around packages, maybe even more often than once a week or just want to say “hi”? Then dm or mail me directly and consider joining my discord server!
Thanks for reading,
Tomáš Falešník