How Axios Automatically Serializes Objects to JSON

Axios streamlines API communication in JavaScript by automatically transforming request payloads from native JavaScript objects into JSON strings. This article explains the internal mechanisms Axios uses to detect plain objects, apply default transformations, set the appropriate HTTP headers, and allow developers to customize serialization behavior.

The transformRequest Pipeline

Axios handles data serialization through an internal configuration array called transformRequest. When you make a request containing a data property (such as in POST, PUT, or PATCH requests), the payload passes through this pipeline before the HTTP request is dispatched.

By default, the transformRequest array contains a function that checks the type of the payload. The core logic executes a check similar to the following:

  1. It verifies if the data is a plain JavaScript object or array using internal helper functions (such as isPlainObject(data)).
  2. If the data is a plain object, Axios passes it to native JSON.stringify(data).
  3. If the data is already a string, a Buffer, an ArrayBuffer, a FormData instance, or a Stream, Axios leaves the data unaltered to avoid corrupting specific binary or encoded formats.

Automatic Header Configuration

Along with converting the payload to a JSON string, Axios automatically manages the request headers:

Automatic Response Deserialization

The automatic serialization process works symmetrically for incoming data. Axios includes a transformResponse pipeline that parses incoming JSON response strings back into native JavaScript objects using JSON.parse(), provided the server responds with a valid JSON format and appropriate Content-Type.

Overriding Default Serialization

If you need to send data in a format other than JSON (such as application/x-www-form-urlencoded), you can override the automatic serialization in two ways:

  1. Manual Serialization: Convert the data using libraries like qs (qs.stringify(data)) or standard objects like URLSearchParams before passing it to Axios.
  2. Custom transformRequest: Provide a custom function in the Axios request configuration to alter the serialization logic globally or per-request:
axios.post('/api/endpoint', data, {
  transformRequest: [(data, headers) => {
    // Custom transformation logic here
    return JSON.stringify(data);
  }]
});