Using fetch with TypeScript
Since fetch
) is pratically universally supported on the most used web browsers, we may safely drop the use Axios and other similar libraries in favor of fetch
. In this article, I'll create a little wrapper for fetch
that adds some conveniences to improve the developer experience.
The code
First, I will create a base function from where all the other shall be derived:
In the code above, we:
- Created a new
HTTPError
class, in order to throw HTTP Errors as they appear; - Use a generic type in order to be able to type the response of the request.
Now, let's extend the query function to enable us to serialize and send data on our requests:
In the code above, we:
- We build a closure that, first, receive the method we want to call and then returns a function where we pass the
url
and thebody
(which is, by default, JSON-stringified) of the request.
At this point, we can use our newly created functions like this:
Fully functional, but not very "ergonomic". I believe that our code should also be able to accept a base URL for all the requests, make it easier to add things on the header (like an authorization token) and an easy way to make PATCH
, PUT
and DELETE
requests.
Let's refactor the code above in order to make it easy to add a base URL and pass a common header to all requests:
In the code above, I:
- Created a
createQuery
function, a closure where I can set a defaulturl
andinit
parameters; - Created a new
query
function, where I use thecreateQuery
function to define the base URL and the default parameters that all requests should have (note the dummygetToken
function that adds a Bearer Token to each request); - In the end, I export the
api
object all the commonly used function to make requests.
You may want to return the body of a request that returned an error, like, for example, when your backend returns the standardized problem details. So, the refactored code would be:
And now, you can use your new wrapper around fetch like this:
Final thoughts
The code above is not full-featured as Axios, redaxios, ky or wretch, but, most of the time, it is all need when I'm working with React using SWR or TanStack Query (and on the backend too). Give me your thoughts about the code and show me your improvements (if you want). You can access this code on this gist.