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