DEV Community

Cover image for Persisting a Node API with PostgreSQL, without the help of ORM's like sequelize.

Persisting a Node API with PostgreSQL, without the help of ORM's like sequelize.

Johnson Ogwuru on October 26, 2018

What do we mean when we use the term 'persist'? Persistence in our everyday English is "the continuance of an effect after its cause is removed", i...
Collapse
 
lionardo profile image
lionardo • Edited

Awesome post, meanwhile I have a question. Can you use template literals for queries? Example:
const query = SELECT sometable FROM students WHERE id=${id};
client.query(query, (error, result) => {...

Collapse
 
dmfay profile image
Dian Fay

You can, but using template literals to interpolate query parameters like you're suggesting opens you up to SQL injection attacks. If the id value is passed from somewhere the user can modify it, someone could supply a value like 3; DROP TABLE users CASCADE; and the driver would happily execute it.

Interpolation like that is also more difficult with strings because of the quoting rules, so it's really never worth it. Prepared statements with $n placeholders are easier and safer.

For Postgres+Node specifically, pg-promise lets you use named parameters and dynamic SQL with prepared statements, which might be worth checking out if you want to avoid having to count params.

Collapse
 
ogwurujohnson profile image
Johnson Ogwuru

Thanks dian

Collapse
 
ogwurujohnson profile image
Johnson Ogwuru

Sorry for the late reply liornado, figured you have gotten the reply to your question, to re echo, yes you can but you might be opening up your app to lots of security issues

Collapse
 
slidenerd profile image
slidenerd

Many standard practices have not been followed
First of all you dont need to call pool.end Check this Github Issue on pg github.com/brianc/node-postgres/is...
Secondly, you havent structured the repo as per the standards mentioned by the repo owner, Check this section of the documentation node-postgres.com/guides/async-exp...
Thirdly you are not using migrations to create the tables, that is how you would do it in production, you should use a package like github.com/salsita/node-pg-migrate to create migration files, then run the DML queries only via pg, I dont have anything against you but an incomplete article such as this sways the newbies into NOT following the standard practices which is bad in the long run, if you dont have the time for rewriting this post, let me know, I ll be happy to correct everything and link back to your post

Collapse
 
vikrantsingh47 profile image
vikrant singh • Edited

is using an orm like sequalize a good idea as we can also write raw sql queries in it?

Collapse
 
ogwurujohnson profile image
Johnson Ogwuru • Edited

Okay

Collapse
 
kodekage profile image
Prosper Opara

Thanks for the awesome piece johnson, it's one of the few tutorials that don't focus on using sequalize.

Update the article to include the part where you import { pool } from services/db.js into the index.js file

Collapse
 
ogwurujohnson profile image
Johnson Ogwuru

Would do, thanks Prosper, for your kind words

Collapse
 
dmfay profile image
Dian Fay

Good on you for avoiding O/RMs, but you don't have to resort to writing SQL for everything, especially if you want to stick to the JavaScript part! There are a couple of options that give you a more "JavaScripty" way to work with your database without the O/RM overhead:

  • query builders like Knex
  • data mappers like (my project) Massive

They have slightly different strengths & so the appropriate choice depends on where you're planning to take this. Query builders do well if you have a lot of one-offs, different joins depending on context, customizable aggregation, and so on. Data mappers are more organized and provide a consistent framework for retrieving and manipulating information.

Collapse
 
ogwurujohnson profile image
Johnson Ogwuru

Thanks for the suggestion,i woudl definitely try them out. Thanks again

Collapse
 
tvmthomson profile image
Thomson Varkey

I am using PostgreSQL functions instead of query the problem facing is the errror. The errors are driven as result here the code follows

router.post('/insert_update_employee', (req, res) => {
debugger;
data = req.body;
pool.connect((err, client, done) => {
const query = 'SELECT insert_update_employee($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12) ';
const values = [data.ID, data.Name, data.DOB, data.ContactNo, data.EmailAddress, data.SupervisorID, data.PositionID, data.HireDate, data.IsSupervisor, data.ImageUrl, data.UserName, data.IsUpdate];
client.query(query, values, (err, result) => {
done();
if (err) {
debugger;
res.status(400).json({ err });
}
debugger;
res.status(202).send({
status: 'SUccessful',
result: result.rows[0]
});
});
});
});

Collapse
 
ogwurujohnson profile image
Johnson Ogwuru

Hi Thomson, sorry for the late reply. Can you explain a little bit further what the problem is? 😉

Collapse
 
wekesamuel profile image
wekesamuel

Hi, can we add multiple files inside here "create": "node ./services/db createTables" , so that instead of it running only the db file, it can also run other files inside the services folder

Collapse
 
ogwurujohnson profile image
Johnson Ogwuru

Sorry for the late reply Samuel, but were you able to try that out?