I’m the founder of Hasura - sharing some notes from how I’ve seen GraphQL usage evolve over the last few years.
1. GraphQL was and remains insanely hard to build without an underlying data layer that does the heavy lifting. Without projection push-down, predicate push-down, a data layer that can support heavy parallelism it’s untenable. Exactly the problems the OP highlights - needing to “hoist”…
2. GraphQL on REST is an anti-pattern. The hype takes you there, but the juice is not worth the squeeze. The problem was lack of types? Add openapi. The problem was custom aggregation endpoints? Make it super easy / cheap to build aggregate endpoints in REST. Use an AI copilot to write an aggregate REST endpoint and a openapi schema for it even. But maybe the last thing to do is to build annd mainatian another API layer with a completely different execution model.
It’s not what it was meant for perhaps, but GraphQL’s killer use-case is an API to access / operate on data. Especially when there are multiple consumers of data (services, apps) and they don’t own the underlying data sources or speak the underlying language of the database. This turns out to be the underlying problem behind a lot of api, data modernization / migration / decomposition efforts.
The cost of this approach is implementing
Graphql by building a compiler/planner with a robust authz system baked into it. A resolver based approach can never cut it, unless you resolve a query plan - aka build a compiler.
If you want to use graphql to just batch rest endpoints, it’s very likely going to become legacy tech as soon as the team that built it starts to move on.
Yates implements Postgres RLS along with Prisma, which we use as our ORM, and then our GraphQL schema is generated using TypeGraphQL (https://typegraphql.com/). Overall, it's a very nice setup and allows us to be versatile on the client side while still having strong authentication integrity.
While perhaps not as polished as Hasura, this stack does have the nice benefit of being free ;-)
1. GraphQL was and remains insanely hard to build without an underlying data layer that does the heavy lifting. Without projection push-down, predicate push-down, a data layer that can support heavy parallelism it’s untenable. Exactly the problems the OP highlights - needing to “hoist”…
2. GraphQL on REST is an anti-pattern. The hype takes you there, but the juice is not worth the squeeze. The problem was lack of types? Add openapi. The problem was custom aggregation endpoints? Make it super easy / cheap to build aggregate endpoints in REST. Use an AI copilot to write an aggregate REST endpoint and a openapi schema for it even. But maybe the last thing to do is to build annd mainatian another API layer with a completely different execution model.
It’s not what it was meant for perhaps, but GraphQL’s killer use-case is an API to access / operate on data. Especially when there are multiple consumers of data (services, apps) and they don’t own the underlying data sources or speak the underlying language of the database. This turns out to be the underlying problem behind a lot of api, data modernization / migration / decomposition efforts.
The cost of this approach is implementing Graphql by building a compiler/planner with a robust authz system baked into it. A resolver based approach can never cut it, unless you resolve a query plan - aka build a compiler.
If you want to use graphql to just batch rest endpoints, it’s very likely going to become legacy tech as soon as the team that built it starts to move on.