You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I just started using the Planetscale serverless driver for JavaScript, but I'm having a hard time understanding it. The documentation explains the very basics but doesn't go into detail on any of the return objects to the provided functions, why you would want to use any of the things provided over the other, nor any caveats I should/shouldn't know. All of the provided objects/classes/types in javascript lack JsDocs.
Having detailed documentation is useful so developers can quickly understand how to use the library without having to tinker and try things out. I've provided some examples below that could be improved on, but it's not a comprehensive list.
The docs say that we can connect to our DB with connect and Client, but they don't explain why I would want to use one over the other apart from this line
Use the Client connection factory class to create fresh connections for each transaction or web request handler.
The Client class has a execute function but also has another function called connection which returns a Connection object, which also has an execute function. Why are there two? Are they actually the same? When do I use one over the other?
There's also no mention of pooling, which I'm not even sure matters for serverless, but I feel like it should be addressed so I'm not overloading my DB with connections.
I'm also assuming that parameterized SQL calls won't cause me to have a SQL injection. You have an article here but it doesn't address this library at all.
The docs say that we can connect to our DB with connect and Client, but they don't explain why I would want to use one over the other apart from this line
I agree that the usage between connect and Client is confusing. Let me try to provide some insights, and hopefully some answers.
Using a global connection can lead to data inconsistencies, because a connection is not really meant to be shared across requests. In practice this means you'll almost certainly want to use Client over the current connect.
We have talked internally about updating the connect function to return a Client instance.
-export function connect(config: Config): Connection {- return new Connection(config)+export function connect(config: Config): Client {+ return new Client(config)
}
But we hadn't yet because of backwards compatibility. Often people use database-js through an ORM eg. Drizzle, Prisma. Older versions of Drizzle (<0.29.4) (and Prisma) did not accept Client instances. This has been patched since and both now enforce the usage of a Client instance (ref).
It's been almost half a year since Drizzle started to accept Client instances - we can start considering changing the defaults now. If people want a single global connection they'd still be able to instantiate one directly.
The Client class has a execute function but also has another function called connection which returns a Connection object, which also has an execute function. Why are there two? Are they actually the same? When do I use one over the other?
They are not the same. By design Client#execute instantiates a new connection for every query you run. Use Client when you don't want to share any connections, use Connection when you do.
There's also no mention of pooling, which I'm not even sure matters for serverless, but I feel like it should be addressed so I'm not overloading my DB with connections.
Database-js is made for being used within serverless environments, you don't have to worry about managing your database connections.
Connection instances are often mistaken for database connections, maybe there's a better name for them. Quoting @mattrobenolt
Connection instances are used to track state, they are more synonymous with a "session". One underlying TCP connection is reused, but for multiplexing over that single TCP connection, the session is required to track state.
Can you speak at all to the parameterized SQL calls and how you prevent SQL injections?
Do you think you will add an API guide to the documentation? I have no plans to use an ORM and fully intend on writing all my own SQL queries and keeping them in my codebase.
Can you speak at all to the parameterized SQL calls and how you prevent SQL injections?
You can either use the built-in escaping, or use an external library, like sqlstring. String interpolation would not be safe. (Ref)
Do you think you will add an API guide to the documentation?
What are you looking for exactly? The API surface is pretty small and should be fully covered with the README. We do welcome any contributions to make things better.
I have no plans to use an ORM and fully intend on writing all my own SQL queries and keeping them in my codebase.
Activity
ayrton commentedon Jul 19, 2024
Thank you for your feedback.
I agree that the usage between
connectandClientis confusing. Let me try to provide some insights, and hopefully some answers.Using a global connection can lead to data inconsistencies, because a connection is not really meant to be shared across requests. In practice this means you'll almost certainly want to use
Clientover the currentconnect.We have talked internally about updating the
connectfunction to return aClientinstance.But we hadn't yet because of backwards compatibility. Often people use database-js through an ORM eg. Drizzle, Prisma. Older versions of Drizzle (<0.29.4) (and Prisma) did not accept
Clientinstances. This has been patched since and both now enforce the usage of aClientinstance (ref).It's been almost half a year since Drizzle started to accept
Clientinstances - we can start considering changing the defaults now. If people want a single global connection they'd still be able to instantiate one directly.They are not the same. By design
Client#executeinstantiates a new connection for every query you run. UseClientwhen you don't want to share any connections, useConnectionwhen you do.@mattrobenolt did a deep-dive into the nuances, I highly recommend reading it if you want to get a deeper understanding. drizzle-team/drizzle-orm#1743 (comment).
Database-js is made for being used within serverless environments, you don't have to worry about managing your database connections.
Connectioninstances are often mistaken for database connections, maybe there's a better name for them. Quoting @mattrobenoltPeytonHanel commentedon Jul 19, 2024
This is super helpful. Thank you so much.
Can you speak at all to the parameterized SQL calls and how you prevent SQL injections?
Do you think you will add an API guide to the documentation? I have no plans to use an ORM and fully intend on writing all my own SQL queries and keeping them in my codebase.
Thank you.
ayrton commentedon Jul 19, 2024
You can either use the built-in escaping, or use an external library, like sqlstring. String interpolation would not be safe. (Ref)
What are you looking for exactly? The API surface is pretty small and should be fully covered with the README. We do welcome any contributions to make things better.
This is perfectly reasonable.
PeytonHanel commentedon Jul 20, 2024
So just to be clear, doing this is safe against SQL injections:
mattrobenolt commentedon Jul 20, 2024
Correct.