serverless-express icon indicating copy to clipboard operation
serverless-express copied to clipboard

How to use Async/await?

Open intern7777 opened this issue 3 years ago • 1 comments

I read https://github.com/vendia/serverless-express/issues/481 https://github.com/vendia/serverless-express/issues/134 and https://github.com/vendia/serverless-express/blob/mainline/examples/basic-starter-api-gateway-v2/src/lambda-async-setup.js but I still cannot figure out how to connect to a database (postgres, not from RDS). A minimal example of what I'm trying to do:

//lambda.js
require('source-map-support/register')
const serverlessExpress = require('@vendia/serverless-express')
const app = require('./app')

exports.handler = serverlessExpress({ app })

//app.js
require('dotenv').config();
const { Client } = require('pg') //leaving out the rest of the libraries
router.post('/createUser', async function (req, res) {
	await sqlRequest(`INSERT INTO users ("name", "age" "ect..")  VALUES ( ${req.body.name}, ${req.body.age}, ${req.body.ect..})`);
	res.status(200).send("inserted!");
})
router.post('/getUser', async function (req, res, next) {
	let result  = sqlRequest('SELECT * FROM users WHERE id = ' + req.body.id) //all user input is escaped in full version
	res.status(200).json(result);
})

async function sqlRequest(sql, params){
	const client = new Client(process.env.DATABASE_URL); //this is a postgres URL
	await client.connect();
	let result = await client.query(sql);
	client.end();
	return result.rows;
}
module.exports = app

The full app is a few hundred lines with many more queries and works fine locally. I believe the issue is being caused by async/await. Is there any way to do this in lambda? If this isn't the right library to use, can someone point me in the right direction? Would you recommend I switch to Azure or some other service to make it easier? Any advice on how to proceed is appreciated.

intern7777 avatar Aug 11 '22 04:08 intern7777

First, make sure you are actually waiting for sql requests, as this line is missing the await keyword:

router.post('/getUser', async function (req, res, next) {
   // correct version: let result = await sqlRequest('SELECT * FROM users WHERE id = ' + req.body.id) // all user input is escaped in full version
   let result = sqlRequest('SELECT * FROM users WHERE id = ' + req.body.id) //all user input is escaped in full version
   res.status(200).json(result);
})

Then. what problems are you having? Any errors being thrown at you? Any latency on requests?

Also, avoid doing this ${req.body.name} because every time you concatenate the string like this in SQL you create a SQL injection. I can literally drop your entire database in getUser just by passing 1;DROP SCHEMA public CASCADE. See the Parameterized Query section in the postgres documentation to learn how to avoid this security issue.

H4ad avatar Aug 13 '22 16:08 H4ad