In my current software development project, we have a monorepo that encases several services. They implement different functionality, but we are trying to reduce redundancy and make maintenance easier for key functions duplicated through each. In this particular case, that’s our HTTP client.
The client we are using is Axios, but we also want to make the client agnostic in case that changes. That means we need to create a reusable module! Where to start?
1. Move the code!
Regardless of how you choose to do this, the new HTTP client needs to be in a centralized area if we intend to reuse the functionality in other places. This way, we have a single source of truth.
One way I’ve found effective, especially if this code is being used in multiple repositories, is to create a private GitHub package scoped to your company’s organization. This can be published and then accessed by any repository within that org structure.
2. Use custom typing!
Custom types are necessary for an agnostic approach. When an out-of-box client is used, in this case, Axios, it comes with a lot of resources built in. For one, Axios has its own types for both responses (AxiosResponse) and errors (AxiosError). These need to be handled in such a way that they’re fed into a custom type that we can control. In this way, we aren’t relying on validating Axios-specific functionality if it needs to get swapped out one day.
3. Look at how the current client is being used today!
A part of our problem is that Axios is being used across different services. However, not all of them are making the same requests. For example, one only makes GET requests, while another uses POST, PUT, and GET. By being able to accommodate every request using our custom client, it’ll be easier to refactor later on.
Loosely Couple Common, Dependency-Agnostic Functionality
There’s a case to be made for using the client-agnostic approach. Maybe a better client will be available one day!