I need to get data from Spotify API then send the response to the front-end. To avoid CORS issue and to hide key and secret from Spotify, I would like to use Lambda to make the API call then send back the response. To be more precise about my application:
1. FrontEnd > API Gateway
2. API Gateway > Lambda
3. Lambda > Spotify API (request their API to get token)
4. Spotify API > Lambda (token in the response)
5. Lambda > API Gateway
6. API Gateway > FrontEnd
Spotify endpoint is:
https://accounts.spotify.com/api/token?grant_type=client_credentials
Header is:
Content-Type: 'application/x-www-form-urlencoded'
Authorization: 'Basic XXX'
So far I was able to do this using a Lambda function:
const https = require('https');
exports.handler = async (event, context) => {
return new Promise((resolve, reject) => {
const options = {
hostname: 'accounts.spotify.com',
path: '/api/token?grant_type=client_credentials',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic XXX'
}
}
const req = https.request(options, (res) => {
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
resolve('Success');
});
req.on('error', (e) => {
reject(e.message);
});
// send the request
req.write('');
req.end();
});
};
But I can't get the response from the API:
{
"access_token": "YYY",
"token_type": "Bearer",
"expires_in": 3600,
"scope": ""
}
And I don't know how to send the data back to the front-end. Do you have any guidance to achieve what I'm looking for?
Edit: I also tried using axios as suggested:
const axios = require("axios");
module.exports.handler = (event, context, callback) => {
const headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic XXX'
}
axios.post('https://accounts.spotify.com/api/token?grant_type=client_credentials', {}, {
headers: headers
})
.then(function(response) {
console.log(response)
callback(null, response);
})
.catch(function(err) {
console.error("Error: " + err);
callback(err);
});
};
But got the following error:
Response:
{
"errorType": "Error",
"errorMessage": "Request failed with status code 400",
"trace": [
"Error: Request failed with status code 400",
" at createError (/var/task/node_modules/axios/lib/core/createError.js:16:15)",
" at settle (/var/task/node_modules/axios/lib/core/settle.js:17:12)",
" at IncomingMessage.handleStreamEnd (/var/task/node_modules/axios/lib/adapters/http.js:237:11)",
" at IncomingMessage.emit (events.js:215:7)",
" at endReadableNT (_stream_readable.js:1183:12)",
" at processTicksAndRejections (internal/process/task_queues.js:80:21)"
]
}
Thanks to @jarmod and @Ashish Modi, the solution below is working for me:
const axios = require("axios");
const querystring = require('querystring');
module.exports.handler = (event, context, callback) => {
const headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic XXX'
}
axios.post('https://accounts.spotify.com/api/token?grant_type=client_credentials', querystring.stringify({}), {
headers: headers
})
.then(function(response) {
const res = {
statusCode: 200,
body: (response.data.access_token)
};
callback(null, res);
})
.catch(function(err) {
console.error("Error: " + err);
callback(err);
});
};