Live data from Hacker News

Efficient GraphQL Queries in Ruby on Rails and Postgres

pganalyze.com

1–10 of 67 posts

Re: Efficient GraphQL Queries in Ruby on Rails and Postgres

#2
> The following query produces the data that we want... we just need to figure out how to write a batch loader that generates the same result.

This is where the abstraction breaks down. Should you care what the query ultimately looks like? For anything beyond a toy, you sure should. But how far should you go to ensure the abstraction produces the implementation you want? Why not just skip to the implementation you want?

Sooner or later, you need to break the abstraction. I'd rather just write the SQL for all my endpoints.

I'm not bullish on GraphQL for the same reason I'm not bullish on ORMs. For some things, an abstraction suffices, but it's far from a universal solution. If I have to break out of the GraphQL abstraction, why bother in the first place? Is there value in a mixed GQL/REST API?

> GraphQL can be as efficient as REST, but requires approaching optimizations from a different angle. Instead of upfront optimizations, we lazy-load data only when required, loading it in batches to avoid excess trips to the database.

Admittedly, the author does a good job of preserving the abstraction, but I'm hesitant to expect most devs to dive this deep, and thus hesitant to expect this level of quality/performance from a GraphQL backend.

Re: Efficient GraphQL Queries in Ruby on Rails and Postgres

#4
Another option for solving the N+1 query problem is to generate a single database query at the root level by inspecting the selection set of the GraphQL query. This is the approach used by Neo4j GraphQL (and other GraphQL database integrations): https://grandstack.io/docs/neo4j-graphql-js.html

Re: Efficient GraphQL Queries in Ruby on Rails and Postgres

#5

> The following query produces the data that we want... we just need to figure out how to write a batch loader that generates the same result. This is where the abstraction breaks down. Should you care what the query ultimately looks like? For anything beyond a toy, you sure should. But how far should you go to ensure the abstraction produces the implementation you want? Why not just skip to the implementation you wa…

> This is where the abstraction breaks down.

No. In REST, the client is responsible for resolving IDs into entities.

In GraphQL, that responsibility largely moves into the backend.

This is not "breaking the abstraction", this is exactly what GraphQL is good for.

Re: Efficient GraphQL Queries in Ruby on Rails and Postgres

#6

Another option for solving the N+1 query problem is to generate a single database query at the root level by inspecting the selection set of the GraphQL query. This is the approach used by Neo4j GraphQL (and other GraphQL database integrations): https://grandstack.io/docs/neo4j-graphql-js.html

That might be doable in Ruby using the Sequel library, but if you are stuck in a Rails codebase using Activerecord, the amount of query complexity until that approach break down is not very big.

Re: Efficient GraphQL Queries in Ruby on Rails and Postgres

#7

> The following query produces the data that we want... we just need to figure out how to write a batch loader that generates the same result. This is where the abstraction breaks down. Should you care what the query ultimately looks like? For anything beyond a toy, you sure should. But how far should you go to ensure the abstraction produces the implementation you want? Why not just skip to the implementation you wa…

> This is where the abstraction breaks down. No. In REST, the client is responsible for resolving IDs into entities. In GraphQL, that responsibility largely moves into the backend. This is not "breaking the abstraction", this is exactly what GraphQL is good for.

It breaks down, when you write an API to solve a task, rather than when you write an API to expose resources and then let the consumer of the API define the task.

Re: Efficient GraphQL Queries in Ruby on Rails and Postgres

#8
post #7

Earlier quoted context omitted.

> This is where the abstraction breaks down. No. In REST, the client is responsible for resolving IDs into entities. In GraphQL, that responsibility largely moves into the backend. This is not "breaking the abstraction", this is exactly what GraphQL is good for.

It breaks down, when you write an API to solve a task, rather than when you write an API to expose resources and then let the consumer of the API define the task.

Well, but that's not breaking down GraphQL as an abstraction, isn't it?

Re: Efficient GraphQL Queries in Ruby on Rails and Postgres

#9

> The following query produces the data that we want... we just need to figure out how to write a batch loader that generates the same result. This is where the abstraction breaks down. Should you care what the query ultimately looks like? For anything beyond a toy, you sure should. But how far should you go to ensure the abstraction produces the implementation you want? Why not just skip to the implementation you wa…

There’s a different way of managing graphs queries. When you remember that you’re effectively running a query per layer of the graphql tree (much like an ORM does) then you can optimise all the stuff that sits in a single layer by creating a view to aggregate as required.

You get to keep the data aggregation complexity in the data layer and then have a loader that sits above it which is effectively just choosing which subsection of the tree to load.

I’d recommend looking at Hasura which does a great job of this.

Re: Efficient GraphQL Queries in Ruby on Rails and Postgres

#10

> The following query produces the data that we want... we just need to figure out how to write a batch loader that generates the same result. This is where the abstraction breaks down. Should you care what the query ultimately looks like? For anything beyond a toy, you sure should. But how far should you go to ensure the abstraction produces the implementation you want? Why not just skip to the implementation you wa…

>For some things, an abstraction suffices, but it's far from a universal solution

Fair, but the ORM covers 80% of what you need. Mapping to objects, autoloading associations. These are simple selects and joins and make up a large portion of most information based systems.

When something needs performance and the ORM isn't optimizing appropriately, sure, drop to raw SQL and optimize away. Even then, what did you gain? Shaving 100 seconds off a 200 second query, sure that's worth it. But if you optimize and manage to shave off a mere five seconds, was it worth it? Maybe. Maybe not.

For most systems where you're displaying information, you just need good enough, an ORM that feels productive and doesn't get in the way (e.g. ActiveRecord).

Post reply on HN