I have node/express apis app. I deploy all apis in one AWS-lambda function using serverless framework.
For some reason, I want to call one of the API routes directly from/within AWS-lambda function.
Node/express serverless app
const express = require("express"); const awsServerlessExpress = require("aws-serverless-express"); const app = express(); const server = awsServerlessExpress.createServer(app) ... const pointsRoute = require("./src/routes/points.route"); ... app.use(`/api/v5.1/points`, pointsRoute); module.exports.handler = (event, context) => { awsServerlessExpress.proxy(server, event, context); } points.route.js
const express = require("express"); const router = express.Router(); const { postPoints } = require("../ctrls/points.ctrl.js"); router.route("/").post(postPoints); module.exports = router; points.ctrl.js
exports.postPoints = (req, res, next) => { console.log("hitting postPoints method"); ... ... } Calling /api/v5.1/points route from javascript directly.
const AWS = require("aws-sdk"); AWS.config.update({ accessKeyId: "id", secretAccessKey: "AccessKey", region: "region" }) const lambda = new AWS.Lambda(); export const invokeLambda = async (points: any) => { return lambda.invoke({ // pls NOTE it always make GET call by default FunctionName: 'my-lambda-fn', InvocationType: 'RequestResponse', Payload: JSON.stringify({ path: '/api/v5.1/points', body: JSON.stringify(points) }), }).promise(); } call invoke method
const result = await invokeLambda(points); With above setup I used to get error that route doesn't exist because /api/v5.1/points is defined with POST method as above.
So what I did: I just added GET method to make sure it hits route with GET method. I updated router code as follow,
const express = require("express"); const router = express.Router(); const { postPoints, getPoints } = require("../ctrls/points.ctrl.js"); router.route("/").get(getPoints).post(postPoints); module.exports = router; In points.ctrl.js just added,
exports.getPoints = (req, res, next) => { res.status(200).send("points being sent !!!"); // this is hitting now with lambda.invoke } Now calling invokeLambda function as below,
await invokeLambda(points); it returns,
{ "statusCode": 200, "body": "points being sent !!!", "headers": { "x-powered-by": "Express", "access-control-allow-origin": "*", "content-type": "text/html; charset=utf-8", "content-length": "33", "etag": "W/\"21-McMNImVhZFYtkiA9PATcy7GTuZU\"", "date": "Tue, 25 Apr 2023 11:12:15 GMT", "connection": "close" }, "isBase64Encoded": false } THEN question is HOW CAN I MAKE POST method call from lambda.invoke? so it can start hitting POST route.
FYI previous question : invoke lambda(node/express - serverless express route) from javascript(reactjs) using aws-sdk
I tried adding POST as below,
return lambda.invoke({ FunctionName: 'my-lambda-fn', InvocationType: 'RequestResponse', httpMethod: "POST" // throws validation error http:{ method : "POST" // throws validation error Payload: JSON.stringify({ path: '/api/v5.1/points', body: JSON.stringify(points) }), }).promise(); Update after creating bounty
Pls check below relevant questions which I asked and didn't receive any answer. This question will help you understand other aspect of the question asked here.
- Asked below question after this question.
Invoking Lambda function from JS doesn't receive payload/body/request object
- Asked below question before this question.
invoke lambda(node/express - serverless express route) from javascript(reactjs) using aws-sdk
POSTsomewhere in the payload. The lambda service does not care about your REST API and the HTTP verbs you use in it. docs.aws.amazon.com/apigateway/latest/developerguide/… - I am surprised it actually works with thepathtop level in the payload.Payloadobject, I tried withhttpMethod:"POST"orhttp:{method:"Post"}but then it throws some validation error and doesn't make request. I really don't know what to add, where to add ?eventto see what it normally contains to understand the difference between invoking the lambda and what the lambda actually is invoked with.eventobject containspayload objectonly. In other words,pathandbodyonly.method: "POST"insidepayload, it still calls GET method.