Here is the code for my server which works fine. I am trying to achieve this with netlify's serverless functions which I have pasted further below.
CODE ON STANDARD SERVER-HEROKU
const ratingController = {};
const Rating = require("../models/ratingModel");
ratingController.getAllRatings = async function (req, res) {
const rating = await Rating.find();
res.status(200).json({
status: "success",
data: rating,
});
};
ratingController.createOneRating = async function (req, res) {
console.log(req.body);
req.body.userIp = req.headers["x-forwarded-for"];
const rating = await Rating.create(req.body);
// const rating = new Rating(req.body);
// await rating.save();
res.status(200).json({
status: "success",
data: {
rating,
},
});
};
PART 1 - GET REQUEST
Here's my code for the getAllRatings and it works fine
SERVERLESS FUNCTION - NETLIFY
const { MongoClient } = require("mongodb");
require("dotenv").config();
exports.handler = async function getData(event, context) {
const client = await MongoClient.connect(process.env.DB, {
useUnifiedTopology: true,
useNewUrlParser: true,
});
const db = client.db();
try {
const slug = event.queryStringParameters.id;
const data = await db.collection("collectionName").find({ slug }).toArray();
client.close();
return {
statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
status: "success",
data: data,
}),
};
} catch (error) {
console.log(error);
return {
statusCode: 400,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
status: "fail",
message: error.message,
}),
};
}
};
My first question for the above is
Just because it works may not mean it's the right way to do it.. I had a few concerns if calling the database each time there's a call is correct and then placing the code the way I have, if it's the way it should be. It's all based on testing and random research. There's no real method being followed so would appreciate some guidance on a more efficient method to do this.
Normally on a regular server the database connection is done just once.. and here I seem to be doing it every time and I am a bit confused if that's ok or not..
PART 2 - POST REQUEST
Here's my code for the POST request createOneRating
SERVERLESS FUNCTION - NETLIFY
const { MongoClient } = require("mongodb");
require("dotenv").config();
exports.handler = async function createRating(event, context) {
const client = await MongoClient.connect(process.env.DB, {
useUnifiedTopology: true,
useNewUrlParser: true,
});
const db = client.db();
try {
console.log(event);
const rating = await db.collection("ratings").insertOne(event.body);
client.close();
return {
statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
status: "success",
data: rating,
}),
};
} catch (error) {
console.log(error);
return {
statusCode: 400,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
status: "fail",
message: error.message,
}),
};
}
};
This one does not work as it says
{
"status": "fail",
"message": "Cannot create property '_id' on string ''"
}
And I guess that's because event.body is not where the data is.. but I am not sure how to get the POST data in a serverless deployment.
So my second question is
How do I retrieve the data sent by a POST request. As there's no request
parameter I am a bit confused.
Also I'd like to add the IP of the user so other than the POST data I'd also need some help on how to do this
req.body.userIp = req.headers["x-forwarded-for"];
Based on my own research, I have answers to the questions and am placing them here for my own reference and for those who might face a similar situation in the future.
Question 1 : Is it ok to make a database connection on every call that's made to a serverless function
It seems it's ok to do this and for those, like me, who thought that maybe it was not the right way to do it, it's definitely not the wrong way. Maybe there's an efficient way to do this and I'd be open to learn more about this if possible. But for now, it's good to know that it's not wrong to connect to the database each time you make a call.
Question 2: How to make a POST request on a serverless as there's no request parameter
I was not aware that the event
parameter is in fact a replacement for the request
parameter and that the headers and body are properties of the event object and can be accessed in the same way ie event.body
and event.headers
. Here's a link that could save you some time to confirm this.
(https://docs.netlify.com/functions/build-with-javascript/#synchronous-function-format)
And if you, like me, don't know if a serverless function can be defined as GET
or POST
or run into an issue where the POST
request gets converted into a GET
when making a function call here's a link that would help.