Connection Pools
Opening a brand-new database connection for every single request is slow and wasteful. A connection pool keeps a set of ready-to-use connections open, handing one out per query and returning it to the pool afterward.
Setting Up a Pool (PostgreSQL Example)
Console Output
Click “Run” to see the console output here.
Querying From a Route
Console Output
Click “Run” to see the console output here.
Never Build SQL Strings by Concatenation
Inserting user input directly into a SQL string (like `SELECT * FROM users WHERE id = ${req.params.id}`) is vulnerable to SQL injection. Always use parameterized queries — placeholders like $1 — where the driver safely escapes values for you.
Parameterized Queries Prevent SQL Injection
Console Output
Click “Run” to see the console output here.
ORMs as an Alternative
Tools like Prisma, Drizzle, and Sequelize sit on top of the raw driver, letting you query using JavaScript/TypeScript objects and methods instead of writing raw SQL strings — trading some control for significantly less boilerplate and built-in protection against injection.
Best Practice
Always use parameterized queries (or an ORM that generates them for you) — never string-concatenate user input into SQL, regardless of how "trusted" the input source seems.