How to Write a Lightweight JavaScript Fetch Wrapper
Learn how to create a JavaScript fetch wrapper under 1kb to streamline API calls and improve your app’s performance.
Frontend development evolved really fast since the adoption of npm modules: hundreds of thousand packages have been released thanks to the Open Source world, making available dependencies for any developer’s need.
However, sometimes the problems we face don’t require a complex logic, meaning we can implement what is required even without installing external dependencies.
This has some advantages:
- You have full control of your code. In case your business logic needs a change in the code, you can directly act on it with no need to wait for a dependency update or mixing logic to trick the package you are using.
- You can implement what you need, nothing else. Most famous modules are amazing because they provide lots of features and flexibility, but do we really need a 30kb bundle for something we can really do with 10 lines of code?
The API client requirements
Almost every web app written in JavaScript needs to handle some logic to trigger HTTP requests and correctly fetch the required data. The community brought tons of solution across the years, starting from the well know request module (now deprecated), to the well-known axios.
Those are surely great abstractions, but we can build something way lighter and with similar features with much less code.
We’ll now build the API client I usually write, depending on the requirements, which include the following features:
- Parse the response
- Handle all requests method
- Attach query params
- Multi-domain
- Handle authenticated requests
Let’s build it step by step together! 🚀
The request wrapper implementation
First of all, let’s write the wrapper function with no extra functionality, which will be the starting point for our implementation. We’ll use the window.fetch built-in function as base request:
Since we want to use this client to parse JSON responses, let’s parse the response when received. In the case of my requirements, I expect to consume an API with a fixed structure, which will always send back an object with two properties, data or error and a boolean success:
Now we can start adding flexibility to our request function, automating some of the option makings like headers and query params:
So far we already have a good result! We are now able to trigger HTTP requests and parse the response easily with no need for any repetitive operation.
However, there is a margin for improvements! What if our app needs to consume multiple services? We may want to adapt the interface to pick a base URL from a selection in case the request is directed to another service. Let’s adapt the script for this purpose:
We are almost done! But how can we make our requests authenticated if a user is logged? We should retrieve from our authentication service the session token (if available), and attach it to the request through the authorization header:
Passing it a conditional spread into the headers object will allow us to override the Authorization property in case we want to pass a custom header.
To finalize our wrapper, I always add some validators for a required field, sometimes could happen to forget passing an environment variable!
As you can see, It’ll throw an error if an environment variable is missing or the path is not a string.
Wrapping up
With less than 70 lines of code, we got a fully working abstraction flexible enough for all the app requirements. You can adapt it as necessary for your app. The code weight is around 1.9Kb, which goes to less than 1Kb when minified 🚀
I’ll leave here for you a gist with the full implementation and some usage examples:
Last updated: