How to use axios in a lamda function

Just started serverless today. Loving it so far. But I would like to call a mailchimp’s API( or any third party REST API) using axios inside an endpoint:

// index.js
const serverless = require("serverless-http");
const express = require("express");
const app = express();
const axios = require("axios");

app.get("/addToBetaUserList", (req, res) => {
  
//  axios.post().then().error() here
});

module.exports.handler = serverless(app);

// serverless.yml

service: serverless-aryora

provider:
  name: aws
  runtime: nodejs6.10
  stage: dev
  region: us-east-1

functions:
  app:
    handler: index.handler
    events:
      - http: ANY /
      - http: 'ANY {proxy+}'
  addUserToList:
    handler: index.handler
    events:
      - http: 
          path: /addToBetaUserList
          method: GET
          cors: true

plugins:
  - serverless-offline

Then I simply access the endpoint here https://8ophlv8iw2.execute-api.us-east-1.amazonaws.com/dev/addToBetaUserList to see if the axios executed the mailchimp api but I’m getting this error:

TypeError: axios.post(...).then(...).error is not a function
    at app.get (/var/task/index.js:34:6)
    at Layer.handle [as handle_request] (/var/task/node_modules/express/lib/router/layer.js:95:5)
    at next (/var/task/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/var/task/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/var/task/node_modules/express/lib/router/layer.js:95:5)
    at /var/task/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/var/task/node_modules/express/lib/router/index.js:335:12)
    at next (/var/task/node_modules/express/lib/router/index.js:275:10)
    at expressInit (/var/task/node_modules/express/lib/middleware/init.js:40:5)
    at Layer.handle [as handle_request] (/var/task/node_modules/express/lib/router/layer.js:95:5)

Any help is appreciated!

I think you are looking for:

axios.post(...).then(....).catch(...)

not

axios.post(...).then(...).error(...)

I’m getting 503 Service Unavailable and then timeout…

That would make sense. The code you are running throws an error and kills the lambda function. So it responds with service unavailable. Did you try using .catch rather than .error?

Yeah, I changed it.

app.get("/addToBetaUserList", (req, res) => {
 axios
    .post(url, user, header)
    .then(function() {
      res.status(200).json({ msg: "Success" });
    })
    .catch(e => {
      res.status(400).json({ msg: e });
    });
}

However, I just found out that if I do it in the format below, I seem to get some response from the axios…

module.exports.hello = function(event, context, callback) {
  axios
    .get("http://595497246b630e00111350f1.mockapi.io/api/users")
    .then(function(d) {
      console.log(d); // has data here!!
    })
    .catch(e => {
      // res.status(400).json({ msg: e });
    });
  const response = {
    statusCode: 200,
    headers: {
      "Access-Control-Allow-Origin": "*", // Required for CORS support to work
      "Access-Control-Allow-Credentials": true // Required for cookies, authorization headers with HTTPS
    },
    body: JSON.stringify({ message: "Hello World!" })
  };

  callback(null, response);
};

Not sure what’s going on behind serverless(app)…Well I will keep reading the doc. Please advice if there is a better/standard practise when it comes to calling external services in Serverless Framework!

1 Like

Oh from the look of this https://www.reddit.com/r/aws/comments/4dlpkr/lambda_call_to_external_api/ looks like I need to deal with something called VPC!

Ok no need for VPC. I do able to call external services inside my nodejs function naturally. Problem comes with mailchimp so now i need to figure what was it! :slight_smile:

2 Likes

You ever figure this out? I’m dealing with the same thing, but for cheetahmail.

Hey sorry for the late reply. Yeah, it’s working fine for me. My problem was I didn’t handle the error returned from mailchimp, and I also opted for the module.exports.yourFunction = ... pattern. Anyway, I will share my code:

// index.js
module.exports.addToBetaUserList = function(event, context, callback) {
  const body = JSON.parse(event.body);
  const auth = {
     username: "kilgarenone",
     password: process.env.MAILCHIMP_API_KEY
  };
 const user = {
   email_address: body.emailAddress,
   status: "subscribed"
 };

axios
  .post(
    `${mailChimp.apiUrl}lists/${mailChimp.preLaunchListId}/members/`,
    user,
    { auth, headers: { "content-type": "application/json" } }
  )
 .then(function() {
    const response = {
      statusCode: 200,
      headers: {
        "Access-Control-Allow-Origin": "*", // Required for CORS support to work
        "Access-Control-Allow-Credentials": true // Required for cookies, authorization headers with HTTPS
      },
      body: JSON.stringify({
      message: "Successfully added to beta user list!"
    })
  };
  callback(null, response);
})
.catch(e => {
  const error = e.response.data;
  const errorResponse = {
    statusCode: error.status,
    headers: {
      "Access-Control-Allow-Origin": "*", // Required for CORS support to work
      "Access-Control-Allow-Credentials": true // Required for cookies, authorization headers with HTTPS
    },
    body: JSON.stringify({
      message: error.title
    })
  };
  callback(null, errorResponse);
 });
};

//serverless.yml
functions:
  app:
    handler: index.handler
    events:
       - http: ANY /
       - http: 'ANY {proxy+}'
  addToBetaUserList:
     handler: index.addToBetaUserList
     events:
        - http: 
            path: addToBetaUserList
            method: POST
            cors: true
     environment:
       MAILCHIMP_API_KEY: ${ssm:mailChimpApiKey}

And that’s it! Hope that helped!:grinning:

1 Like

This helped me!!
Thanks @kilgarenone

Thank you guys for your replies it really helped to solve my problem I’ve been dealing with it for a long time thanks
192.168.100.1 192.168.1.1