I'm sending a POST request to the crypto.com public API (reference) using node-fetch
. More specifically, I'm am attempting to call the private method get-account-summary and I am signing the request beforehand with my API Key and my Secret Key as prescribed on their API reference page (see digital signature).
const requestBody = JSON.stringify(signRequest(request, apiKey, apiSecret));
fetch('https://api.crypto.com/v2/private/get-account-summary', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: requestBody
})
.then(response => response.body)
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
The request is apparently successful, but I'm struggling to make sense of the API response which is supposed to look like this:
{
"id": 11,
"method": "private/get-account-summary",
"code": 0,
"result": {
"accounts": [
{
"balance": 99999999.905000000000000000,
"available": 99999996.905000000000000000,
"order": 3.000000000000000000,
"stake": 0,
"currency": "CRO"
}
]
}
}
but this is what I actually get:
Success: PassThrough {
_readableState: ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: [],
flowing: null,
ended: true,
endEmitted: false,
reading: false,
constructed: true,
sync: false,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
destroyed: false,
errored: null,
closed: false,
closeEmitted: false,
defaultEncoding: 'utf8',
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: false,
dataEmitted: false,
decoder: null,
encoding: null,
[Symbol(kPaused)]: null
},
_events: [Object: null prototype] {
prefinish: [Function: prefinish],
error: [Function (anonymous)]
},
_eventsCount: 2,
_maxListeners: undefined,
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: true,
needDrain: false,
ending: true,
ended: true,
finished: true,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
afterWriteTickInfo: null,
buffered: [],
bufferedIndex: 0,
allBuffers: true,
allNoop: true,
pendingcb: 0,
constructed: true,
prefinished: true,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
errored: null,
closed: false,
closeEmitted: false,
[Symbol(kOnFinished)]: []
},
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: null
}
You may have noticed that I logged the response.body
to the console rather than the response.json()
because whenever I call the latter, I get an "invalid json error"
Error: FetchError: invalid json response body at https://api.crypto.com/v2/private/get-account-summary reason: Unexpected end of JSON input at C:\Users\...\app\node_modules\node-fetch\lib\index.js:273:32 at processTicksAndRejections (node:internal/process/task_queues:96:5) { type: 'invalid-json'
CodePudding user response:
Fetch returns a response stream. A simpler approach would be to use npm request
package.
Ex :
const request = require('request');
const requestBody = JSON.stringify(signRequest(request, apiKey, apiSecret));
request('https://api.crypto.com/v2/private/get-account-summary', {
json: true,
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: requestBody
})
.then(response => response.body)
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
CodePudding user response:
Many API stacks work in terms of 2 promises:
- Make the remote request
- Deserialize the response
According to docs you need to await the .json()
call.
import fetch from 'node-fetch';
const response = await fetch('https://httpbin.org/post', {
method: 'post',
body: JSON.stringify(body),
headers: {'Content-Type': 'application/json'}
});
const data = await response.json();
Nested promises looks messier when using then
, which is why many people prefer the
async await syntax, but this will work:
request('https://api.crypto.com/v2/private/get-account-summary', {
json: true,
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: requestBody
})
.then(response => {
response.json()
.then(data => {
console.log(data);
})
})
CodePudding user response:
EDIT: Sorry I missed the end of the question. If json()
is invalid and the text()
returns nothing, I would say you should check your request body. The request is successful, but you get an empty response.
Not sure why you are using response.body
. You need to use json()
if you want the response in a JSON format. This will take the body and return a promise which resolve to the requested format. You can read it here.
So, your code should look like this:
fetch('https://api.crypto.com/v2/private/get-account-summary', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: requestBody
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});