Is it possible to POST a responseType: 'stream' in Axios?
Asked Answered
I

2

11

I am attempting to edit an instance of Axios so that the response type should be a 'stream' rather than standard JSON.

It doesn't seem clear to me from other posts on S.O. how this can be accomplished.

Is this a dead-end??

My Current Axios Instance :

import axios from 'axios';
import { URL } from '../urls';
import {
  requestHandler,
  successHandler,
  errorHandler,
} from './Handlers';

const Api = axios.create({
  baseURL: `${URL}`,
  withCredentials: true,
});

Api.interceptors.request.use((request) => requestHandler(request));
Api.interceptors.response.use((response) => successHandler(response), (error) => errorHandler(error));

export default Api;

Implemented :

const query = {"selections":{"TABLE_A":["COLUMN1"]},"filters":[{"predicates":[]}],"joins":[],"sorts":[],"limit":100,"offset":0}
const response = await Api.post('/data', query);

The axios signature for post looks like this :
axios.post(url[, data[, config]])
Example 1
Example 2

This signature doesn't seem to indicate that the newly created instance of axios has a property relating to streams. Ideally, I would be able to do something like this:

const response = await Api.post(URL, responseType: 'stream', query);

or potentially :

const response = await Api(responseType: 'stream').post(URL, query);
Inextensible answered 3/2, 2020 at 22:43 Comment(0)
I
13

While it seems possible to specify a responseType of 'stream' like this :

const response = await Api({
    url: '/data',
    method: 'POST',
    responseType: 'stream',
    data: query
}); 

Axios' xhr.js file will throw this warning in the browser :

The provided value 'stream' is not a valid enum value of type XMLHttpRequestResponseType.

Digging a bit further into the documentation :
Axios Request Configuration indicates that 'stream' is an acceptable responseType. Specifically, if you take a look within axios/index.d.ts :

export type ResponseType = 
  | 'arraybuffer' 
  | 'blob' 
  | 'document' 
  | 'json' 
  | 'text' 
  | 'stream' 

However, the WHATWG spec for an XMLHttpRequest shows that 'stream' isn't valid :

enum XMLHttpRequestResponseType {
  "",
  "arraybuffer",
  "blob",
  "document",
  "json",
  "text"
};

The issue is that the XhrAdapter is used by Axios when making requests from the client-side / in the browser. If Axios is on the server-side, the HttpAdapter will be used. The XhrAdapter will need to make XMLHttpRequests but the server can make HttpRequests, so there are TONS of posts about handling streams in Node with Axios, since Node is a backend solution.

It doesn't appear to be possible to stream results with Axios on the client-side. fetch() may be the only option.

Inextensible answered 4/2, 2020 at 16:53 Comment(8)
Thanks for the detailed answer. Is there a benefit to using stream over arraybuffer? This answer suggests arraybuffer is better than blob for binary images (https://mcmap.net/q/245188/-how-does-axios-handle-blob-vs-arraybuffer-as-responsetype) but is there an advantage to stream over arraybuffer for binary images?Germiston
An ArrayBuffer has a fixed length and cannot be manipulated. Streams allow for manipulation by piping contents to another API mid-stream. I am not positive, but I believe that an ArrayBuffer also would require an object to be fully loaded into memory before sending a chunk of data, whereas a Stream sends a packet as soon as it can.Inextensible
Thanks for the reply. So you can use streams when downloading an image like ones from the Twitter AP (with backend code)? They're not required for live streams of data?Germiston
If you are using axios and have direct access to Twitter's backend, then you can define a stream with axios. If you are requesting access to the image over HTTP, then you will have to use an XMLHttpRequest which does not support a stream. The issue on GitHub is still open, but the comments show some people's solutions. The fetch API is probably the best solution right now (without using a 3rd party solution) since that is meant to provide a readable stream as a response body type.Inextensible
Thanks for the fast response. To clarify, you're saying axios for downloading images from Twitter will not work? Which GitHub issue are you referring to? Thanks for your help!Germiston
Axios Issue 479Inextensible
Downloading images can work, but I'm just saying that you can't define a stream response body type with axios right now. You can download an image with axios as a blob or some other data structure, but in order to stream the bytes you will need to use some other solution like the fetch APIInextensible
Hi @Torc. I just sent a message, but it seems we missed each other. Could you please email info -at- hotpot dot ai? Yes, we need guidance (no coding) on questions like this: #67225819. This is for helping people use our AI services via Twitter bots.Germiston
S
-1

I am using Axios library with Twitter Stream API but only with GET Method. Beginning of the code:

const streamTweets = async (socket,token) => {
    let stream;
    
    const headers = {
        'Authorization':"Bearer "+BEARER_TOKEN,
    }
    const options = {
        method:"GET",
        url:streamURL,
        headers:headers,
        timeout:31000,
        stream:true,
        responseType:"stream"
    };

    try {
        console.log("Uruchamiam funkcję streamTweets");
        // const stream = await axios(options);
        axios(options).then(respobj => {

I believe both options - stream and responseType - must be set. However if you work with Twitter Stream API using socket.io library be aware it might be buggy as after socket emit event no code is executed afterwards. I pointed that out to Socket developers but 6 months are passed and nothing there.

Shull answered 11/9, 2021 at 13:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.