4 ms·
> But SQL is strictly more powerful. I'm not sure I understand. GraphQL doesn't need to be, nor is it meant to be, powerful. Its only purpose in life is to rol
by randomdata 3y ago
> But SQL is strictly more powerful.
I'm not sure I understand. GraphQL doesn't need to be, nor is it meant to be, powerful. Its only purpose in life is to roll up multiple actions into a single response made from a single request. It was originally designed for those actions to be REST/RPC endpoints, but if you have an SQL API endpoint the same applies.
SQL as an API isn't some novel thing. Your DBMS already does exactly that! We've been using SQL as an API for 50-some-odd years and will probably still be using it for APIs in 50 more. But, there is good reason why we have added layers on top in the datacenter. Don't expect SQL to be a suitable API for the entire world to use.
> which allows to aggregate all necessary data within the same SQL query and being returned as a single response.
If you push SQL to really pained lengths it can be done, but with a whole lot of added overhead elsewhere. There is no free lunch. Best to leave SQL to the job it was designed for; the job it is good at. It's okay to let it have help.
- valenterry 3y ago> Yes, if you push SQL to really pained lengths it can be done, but with a whole lot of added overhead that isn't necessary. I still don't get your point. Maybe a conrete example helps: listing the contents of a user's posts. In graphql: users(id: "x") { postIds # don't really need those posts { text } } Here, if this is stored in SQL, there will probably be 3 tables: users, userposts and posts. All conntected by the respective postId. GraphQL is nice here, because instead of making a query to get the user's postIds and then one ore more queries to get each post's content, with GraphQL we only need one network trip. If the backend is half stupid, it will run 2 SQLs here. If it's smart, it will resolve the whole thing with one join. So far there is no performance benefit over writing a single SQL with a join and having the backend execute it directly. Still, I want to emphasize that I'm not advocating to do the latter - it has various drawbacks. But just im terms of performance, there is no disadvantage for the SQL solution. Even if we look at running 2 completely different semantical queries in the same graphql request, we can do the same in SQL with a width-clause. With the technique shown in the article, it's really easy to support that in the API.
- randomdata 3y ago> If it's smart, it will resolve the whole thing with one join. Yes, as a practical engineer that is what you would do to deal with the overhead you have encountered in the datacenter, but you would realize that you are abusing SQL to hack around overhead issues. That is not what you would do in a less constrained environment. Logically, users and posts are distinct relations as it pertains to that example. They have no business being joined here. There is a place for joins, but that's not it. So already, for the simplest case imaginable, you are using SQL outside of the way it was designed to be used. Which is fine if it gets the job done. Purity can step to the side for the sake of engineering, of course. We are not purists here. But as the complexity ramps up, there will be a point where it stops being a decent tradeoff and enters a point of being ridiculous – where you've ended up recreating GraphQL... but poorly.
- valenterry 3y ago> Logically, users and posts are distinct relations as it pertains to that example. They have no business being joined here. There is a place for joins, but that's not it. So what would you do in your world? Run one SQL to get the post's ids and then run another query with that list to get the content for those posts?
- randomdata 3y agoIf you were to use SQL as designed, with an idealized implementation, you would first query the users and then run a query for each user to retrieve the the corresponding posts. That is what the example given describes. I know that's not exactly practical in the real world. Maybe if you dataset is tiny you can get away with it, but any more you'll soon be killed by the overhead of all those queries in the datacenter, let alone over flaky networks. So, in the real world you have to find a workaround. Using a join here is a decent workaround with decent tradeoffs. You can condense what might be hundreds of queries into one. It does not come free. There is no free lunch. But the tradeoffs are acceptable in a lot of cases. But we're also talking about the simplest case imaginable. While it is a reasonable tradeoff for that simple example, those hacks don't scale particularly well as the complexity grows. SQL is not designed for one query to return everything and the kitchen sink.