简体   繁体   中英

How to return a promise from Lambda

I'm trying to connect my NextJS application via AWS Amplify to the Google Calendar API. I added an API with "Amplify Add API". Selected "Rest" and chose "Serverless Express Function". So far so good. The test function works. I am utilizing Proxy integration to let lambda decide what to do with the code. Here is my client side code:

 import React from "react"; import { API } from "aws-amplify"; const getCalendar = () => { React.useEffect(() => { getCal(); async function getCal() { const apiName = 'gcal'; // api name. const path = '/events'; // API path await API.get(apiName, path).then(response => { console.log(response) }).then(() => console.log(` the resopnse returned successfully as: ${JSON.stringify(response.body) }`)).catch(error => { console.log(`there was an error returning the response from the lambda function: ${error}`); }); } },[]) } export default getCalendar;

Inside the Lambda function I started with the Proxy Integration sample and replaced with the code below. The issue is, the response is visible and correct from Google API but not received by the client from Lambda. I tried a callback, async/await, and res.send(). I know I'm missing something in this function below regarding the async nature of the request. Getting 500 or 502 errors from Cloud Watch Logs. Lambda index.js code(with problem):

 const awsServerlessExpress = require("aws-serverless-express"); require("dotenv").config(); var express = require("express"); var bodyParser = require("body-parser"); var awsServerlessExpressMiddleware = require("aws-serverless- express/middleware"); const { google } = require("googleapis"); const calendar = google.calendar("v3"); var app = express(); const server = awsServerlessExpress.createServer(app, null); app.use(bodyParser.json()); app.use(awsServerlessExpressMiddleware.eventContext()); app.use(function (req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "*"); res.header("Content-Type", "*"); next(); }); exports.handler = (event, context) => { return awsServerlessExpress.proxy(server, event, context, "PROMISE").promise; }; app.post("/events", function () { main(); async function main() { const auth = new google.auth.GoogleAuth({ keyFilename: "./<my-secret-file>.json", scopes: [ "https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly", ], }); const now = new Date().toISOString(); // Acquire an auth client, and bind it to all future calls const authClient = await auth.getClient(); google.options({ auth: authClient }); // Do the magic let response = await calendar.events.list({ calendarId: process.env.API_CALENDAR_ID, showHiddenInvitations: false, timeMin: now, showDeleted: false, }); return await response.json(); } return res.send(response); }); app.listen(3000, function () { console.log("Google Calendar Function Is Running"); });

Here is the working response from Google API to Lambda in Dev Tools: 在此处输入图像描述

I am receiving {"message": "Internal server error"} after completion. Here is the failed attempted response to the client from Lambda: 在此处输入图像描述

inside Cloud Watch Logs I get "no help", and a succeeded response: 在此处输入图像描述

Any help or suggestions would be greatly appreciated.

I found out the answer was in both mixing promises with async await and also with res.send(). After returning the data from Google API I still needed to format the response and set the correct headers. Here is the working code.

const awsServerlessExpress = require("aws-serverless-express");
require("dotenv").config();
var express = require("express");
var bodyParser = require("body-parser");
var awsServerlessExpressMiddleware = require("aws-serverless- 
express/middleware");
var app = express();
const server = awsServerlessExpress.createServer(app, null);

app.use(awsServerlessExpressMiddleware.eventContext());
app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "*");
  res.header("Content-Type", "application/json");
  next();
});
app.use(bodyParser.json());

const { google } = require("googleapis");
const calendar = google.calendar("v3");
exports.handler = (event, context) => {

  return awsServerlessExpress.proxy(server, event, context, 
"PROMISE").promise;
};
app.get("/events", function( req, res ) {

  async function main() {
    try {
    const auth = new google.auth.GoogleAuth({
      keyFilename: "./my-secret-file.json",
      // Scopes can be specified either as an array or as a single, 
space-delimited string.
  scopes: [
    "https://www.googleapis.com/auth/calendar",
    "https://www.googleapis.com/auth/calendar.readonly",
  ],
});
const now = new Date().toISOString();
// Acquire an auth client, and bind it to all future calls
const authClient = await auth.getClient();
google.options({ auth: authClient });


let responseBody = await calendar.events.list({
  calendarId: process.env.API_CALENDAR_ID,
  showHiddenInvitations: false,
  timeMin: now,
  showDeleted: false,
});
// Do the magic
let response =
{
  "isBase64Encoded": "false",
  "statusCode": "200",
   "headers": {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Headers": "*",
      "Content-Type": "application/json",
      "Access-Control-Allow-Methods": "*"

   },
  "body": responseBody,
};

   return res.send(JSON.stringify(response))
  } catch (error) {
  console.log(error);
}}
main();
});

app.listen(3000, function () {
  console.log("The Google Calendar Function Is Running");
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM