What does HackerNews think of slonik?
A Node.js PostgreSQL client with runtime and build time type safety, and composable SQL.
I don't think it's necessary to use Zod/runtime validation everywhere, but it's a nice tool to have on hand.
The example you gave actually isn't valid, because what you're doing is generating SQL dynamically, and that doesn't work the way prepared statements work. That is, you can't have a prepared statement like "select foo from bar where zed = ? order by ? asc", because with prepared statements the question marks can only substitute for VALUES, not schema names. So if you wanted to do something like that it slonik, it would fail. With slonik you CAN do dynamic SQL, that is guaranteed to be safe and checked at compile time with TypeScript, because you can nest SQL tagged templates. That is you can do this:
const colToSortBy = useFoo ? sql`foo` : sql`bar`;
const query = sql`select col from mytable order by ${colToSortBy}`;
In that case slonik will know how to safely "merge" the parent and child parsed SQL.I generally reach for TypeORM and have tried MikroORM lately but didn’t really like it.
But what I really want is something like slonik which is more focused on querying than relational mapping.
https://jawj.github.io/zapatos/
Still fundamentally manipulating SQL text (which is a feature as I don't want to learn a full DSL), but it handles wrangling embedded placeholders while you're composing stuff and some other common compositional tasks. It's worked well for me anyway but I'm under no illusions it'd be right for everyone.
Not an original concept regardless; my original version of this was in Node: https://github.com/bdowning/sql-assassin, but a few years after I wrote that (and mostly didn't use it) I found https://github.com/gajus/slonik which was very similar and much more fleshed-out; I rolled _some_ of its concepts and patterns into sql-athame.
https://gajus.medium.com/stop-using-knex-js-and-earn-30-bf41...
Our app doesn't have a huge need for caching, but we use a mix of in-server-memory caching ( https://github.com/isaacs/node-lru-cache ) and Redis when we need a global cache.
It takes advantage of a somewhat-not-well-known feature of Javascript template literals in that you can apply functions to them, e.g. sql`SELECT foo FROM bar WHERE id = ${userEnteredValue}`. No need to manually escape userEnteredValue, the sql template literal function does it for you.
Another one in a similar vein with strict typing and really nice SQL interpolation for Postgres: https://github.com/gajus/slonik
Action text in RoR <=> DraftJS (Isomorphic ReactJS plugin with server side rendering), Froala (compatible with most of SPA frameworks)
Active Record in RoR <=> SequelizeJS (ORM), Slonik(Non-ORM, my recommendation) in NodeJS
Action Cable in RoR <=> WS, Socket.io 2.0 (recommended)
DraftJS - https://github.com/facebook/draft-js
Froala - https://www.froala.com/wysiwyg-editor
SequelizeJS - https://sequelize.org/master/
Slonik - https://github.com/gajus/slonik
WS - https://github.com/websockets/ws
Socket.io - https://socket.io/