Search code examples
sqlnode.jsknex.js

Is it pointless to use Knex if I prefer using raw over its built-in functions?


I know Knex has various benefits, which is why I am contemplating using it for my Node application. I have used it before, and I really enjoy writing the raw queries with it. (Note: I'm still in the learning stages for Knex.) Personally, I think they make the code look slightly better than using basic SQL. It's from this point that my question stems, because maybe my preference is silly here.

I would also love opinions on the built-in functions for Knex. For people who prefer those over using raw, what do you like about them? I am aiming for consistency in my application regardless of the route I choose.

Thanks for your input!


Solution

  • It's not pointless. It depends a bit on whether you're working in a team environment, who else is likely to have to maintain it, and how comfortable they are with writing SQL queries. Note that many things that can be done with Knex can also be done with a direct database driver, so as with many technology choices it comes down to personal/team preference and ease of maintenance.

    Even assuming you never use the query builder, Knex offers:

    • relatively simple configuration according to the current NODE_ENV
    • connection/pool management
    • easy parameterisation
    • easy transactions
    • easy migrations and seeding

    Why not use .raw? Well it's taster's choice, and query builders aren't for everyone. However, query builder fans will tell you:

    • it can be easier to migrate between database backends when you're not dealing with a bunch of raw SQL
    • many people find Knex syntax easier to read, given the population of people who can reasonably understand a JavaScript promise chain likely outweighs those who grok SQL
    • it tends to be rather more compact
    • it provides a level of name/syntax safety (and transpile-time type safety and editor support if you're using TypeScript) over .raw.

    Query builders also lend themselves nicely to composition, so the likes of:

    const userPhoneNumbers = knex('users').select({ id, email });
    
    // later...
    const gmailUsers = userPhoneNumbers.where('email', 'ilike', '%gmail.com');
    
    // still later...
    return gmailUsers.where('email_confirmed', true);
    

    A contrived example, but it can be quite expressive when dealing with less trivial requirements.