johnburnsonline.com

Mastering Axios: Elegant Encapsulation Techniques for Developers

Written on

Chapter 1: Introduction to Axios Encapsulation

Many articles discuss Axios encapsulation, yet doubts often arise during implementation. The question remains: do these advanced encapsulations complicate Axios usage?

High-quality encapsulation should possess the following traits:

  1. Enhancement of Native Framework Limitations: Identify and rectify the shortcomings of the native framework without introducing new issues.
  2. Preservation of Original Functionality: Ensure that all native API functions can still be accessed through the new API.
  3. Ease of Understanding: Developers familiar with the native framework should quickly adapt to the re-encapsulated APIs.

Next, I will delve into low-level encapsulation before exploring more elegant methods.

Section 1.1: Low-Level Encapsulation

Low-level encapsulation involves creating a new API that simplifies specific methods while limiting parameter exposure. Here’s an example code snippet:

export const post = (url, data, params) => {

return new Promise((resolve) => {

axios

.post(url, data, { params })

.then((result) => {

resolve([null, result.data]);

})

.catch((err) => {

resolve([err, undefined]);

});

});

};

In this code, the Axios post method is encapsulated to handle errors without requiring try-catch blocks. However, this method only exposes three parameters: url, data, and params. While these are adequate for many straightforward requests, they may not suffice for more complex scenarios, such as needing to set a longer timeout for slow responses.

For instance, in a specific situation, you might use:

axios.post("/submit", form, { timeout: 15000 });

There are various special cases to consider, including:

  • Uploading forms with both data and files, necessitating the headers["Content-Type"] to be set to "multipart/form-data", along with the onUploadProgress attributes.
  • Managing data races by using cancelToken or signal. Although some suggest using interceptors for this, it could lead to complications, especially when multiple dropdowns request the same options.

Some argue that such special interfaces are rare, but a project’s evolving requirements can introduce new complexities. To prepare for future enhancements, keep the encapsulation aligned with the original API to avoid cumbersome modifications later.

Section 1.2: Creating Axios Instances

You can encapsulate Axios by creating instances or defining a custom Axios class. Here's an example:

const createAxiosByInterceptors = (config) => {

const instance = axios.create({

timeout: 1000,

withCredentials: true,

...config,

});

instance.interceptors.request.use(...);

instance.interceptors.response.use(...);

return instance;

};

class Request {

instance: AxiosInstance;

interceptorsObj?: RequestInterceptors;

constructor(config: RequestConfig) {

this.instance = axios.create(config);

this.interceptorsObj = config.interceptors;

this.instance.interceptors.request.use(

this.interceptorsObj?.requestInterceptors,

this.interceptorsObj?.requestInterceptorsCatch,

);

this.instance.interceptors.response.use(

this.interceptorsObj?.responseInterceptors,

this.interceptorsObj?.responseInterceptorsCatch,

);

}

}

These methods allow for creating multiple Axios instances with different configurations and interceptors. However, maintaining a single Axios instance is advisable, as multiple instances can complicate code understanding and increase the onboarding time for new developers.

Section 1.3: Handling Multiple Configurations

If you have different configurations for various interfaces, define constants for each configuration. For example:

const configA = { /.../ };

const configB = { /.../ };

axios.get("api1", configA);

axios.get("api2", configB);

This approach is more intuitive and allows readers of the code to easily identify differences compared to using multiple Axios instances.

Section 1.4: Managing Multiple Interceptors

If different interceptors are needed, you can mount them on a globally unique Axios instance and selectively execute them based on a custom attribute:

instance.get("/api", { enableIcp: true });

In the interceptor, you can control logic execution based on this attribute:

instance.interceptors.request.use((config) => {

if (config.enableIcp) {

//...

}

return config;

});

This method allows for precise control over which interceptors are executed without cluttering the codebase.

Chapter 2: Elegant Encapsulation

The elegant encapsulation approach simplifies usage as follows:

apis[method][url](config);

The response type will be:

{

data: null | T;

err: AxiosError | null;

response: AxiosResponse | null;

}

Section 2.1: Intelligent URL Derivation

This method supports intelligent parameter deduction based on the URL. If a required parameter is missing, TypeScript will raise an error.

Section 2.2: Smart Result Derivation

For example, for a GET request at /admin, the expected return type would be:

{ admins: string[] }

Section 2.3: Error Handling without Try-Catch

You can simplify error handling without needing to write try-catch blocks:

const getAdmins = async () => {

const { err, data } = await apis.get['/admins']();

if (err) {

//...

return;

}

setAdmins(data!.admins);

};

Section 2.4: Support for Path Parameters

For path parameters, intelligent deduction is also supported:

const getAccount = async () => {

const { err, data } = await apis.get["/account/{username}"]({

args: { username: "123" },

});

if (err) return;

setAccount(data);

};

Finally, thank you for reading! I look forward to your continued support and hope you enjoy more insightful articles.

For additional content, check out PlainEnglish.io. Sign up for our free weekly newsletter and follow us on Twitter, LinkedIn, YouTube, and Discord. If you're interested in scaling your software startup, explore Circuit.

The video titled "How to Encapsulate Axios Elegantly with React JS" provides a comprehensive guide on effective encapsulation techniques.

The second video, "How to Make HTTP Requests like a Pro with Axios," further enhances your understanding of Axios usage in real-world applications.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Embracing Spiders: A Pathway to Spiritual Awareness

Discover the spiritual significance of spiders and how they can guide you towards personal growth and balance.

generate a new title here, between 50 to 60 characters long

An exploration of H.P. Lovecraft's

The Cold War's Space Cemetery: Junk in the Sky and Climate Change

Exploring the connection between space debris and climate change, highlighting the implications of our expanding space exploration efforts.

Mastering the Yield* Keyword in JavaScript Generators

Discover how the yield* syntax in JavaScript generators enables seamless delegation to other generators and iterables.

Reviving Vibrant Smartphone Colors: A Call to Action

A reflection on the shift from bold smartphone colors to muted tones, exploring the implications for design and consumer choice.

Exploring February's Tarot: Insights and Reflections

Dive into February's Tarot reading to gain clarity and alignment for personal growth.

Navigating the Future: Are We Prepared for the Internet of Bodies?

A deep dive into the implications of the Internet of Bodies, exploring its potential benefits and risks for society and individuals.

You Control the Cost of Your Advancement

Explore how knowledge and experience shape our progress and the choices we make regarding time and money.