5 ms·
> Most Web Applications are just forms that talk to a database. And this is why the author is frustrated - GraphQL is designed for larger, more complicated sys
by salmonellaeater 5y ago
> Most Web Applications are just forms that talk to a database.
And this is why the author is frustrated - GraphQL is designed for larger, more complicated systems. It's overkill for a basic web app like this. In fact, coupling the different declarations together like this defeats the purpose of GraphQL.
One of GraphQL's purposes is to let the different layers and parts of a system evolve independently. For instance, the database schema can be changed without changing the GraphQL schema. A resolver can be changed to pull data from a new service instead of the old monolith. It also affords more custom implementations, where the db schema is not exposed directly to the client or the data is stored across multiple technologies.
There's a larger point here, which is that it's okay to have multiple definitions for things that seem similar. It's okay to have one version of a User for the front-end, a different one in the GraphQL layer, and several different ones with varying details in different backend services. The key is that these Users are different things - for each context, there is a useful definition of User that is different from other contexts [1]. Some systems need security details, some need contact info, some only care about the user id, etc.
It's really important in large engineering orgs to allow these different definitions to vary independently so that teams can make incremental changes without updating every single other system. Hence tools like GraphQL.
[1] https://martinfowler.com/bliki/BoundedContext.html https://martinfowler.com/bliki/BoundedContext.html
- bitL 5y agoGraphQL is extremely badly designed - try to do nested pagination, that's basically unsolvable in a single server roundtrip. The hack of keeping an n-dimensional array of pointers to cover each level of pagination falls apart with any concurrent changes. And nested pagination pops up often when doing advanced UI on mobile on web.
- danjac 5y agoEfficiency often takes a back seat to Conway's Law.
- infogulch 5y agoThe "nested pagination with a single server roundtrip" requirement seems a little odd, I'm not sure why that's necessary or desired. I can imagine an example, a view with a list of users, then expanding one user inline to view a list of their comments. But I don't see why I'd even want this whole nested view to be returned in one round trip, it seems quite wasteful to return the first page of comments for every user before it's expanded. Do you have a better example?
- andrewingram 5y agoThe need for hitting nested “paged” data structures on first render isn’t that contrived, but I’ve never found myself needing to juggle the cursors, since you’re usually only hitting the first page for the nested ones. Loading subsequent pages would be a standalone query, rather than running the root query again with different cursors. (the example I came up with for this article a few years has a fairly realistic example of nested pages: https://andrewingram.net/posts/optimising-your-graphql-request-waterfalls/ https://andrewingram.net/posts/optimising-your-graphql-reque...)
- adsharma 5y agoWhat does an ideal solution look like in your view? Do snapshot queries help, so you're protected from concurrent changes? With fquery (https://adsharma.github.io/fquery/ https://adsharma.github.io/fquery/), the problem boils down to constructing a new query with additional where clauses. Because of the property that the shape of the query and the shape of the output are identical, nested queries fit naturally into the system, as opposed to GraphQL <-> SQL where one is nested, but the other is flat, requiring a mapping.
- SkyPuncher 5y agoREST has the same issue.
- hn_throwaway_99 5y agoHallelujah. I see all these posts about auto generating GraphQL from your DB schema and I always think "But you're literally getting rid one one of the best parts of GraphQL by tightly coupling your DB to your API". I also feel that this approach is putting people in for a world of hurt: it's easy to get up and running quickly, but it will kill productivity later on when it makes refactoring much more difficult. FWIW I define my API using the GraphQL schema language and then generate everything after that (Typescript definitions for server and client) using graphql-codegen and it works great.
- BulgarianIdiot 5y agoI find these DB-to-REST, DB-to-GraphQL and so on variety frameworks to be terrible. That said I've come to accept some people really just need to expose their database out there. And so having these tools help them. It would be nice if those tools did provide for a smooth path from 1:1 mapping to full customization. Unfortunately, most don't.
- jensneuse 5y agoI completely agree with you. I've also wrote this post explaining why tightly coupling the DB to the frontend is such a big problem: https://wundergraph.com/blog/tight_coupling_as_a_service https://wundergraph.com/blog/tight_coupling_as_a_service That said, I've added support for direct DB access to WunderGraph based on demand from the community. Although it has drawbacks, users want to expose their DB as an API. I don't want to ignore them. That said, I also want to address your second point. WunderGraph offers two abstraction points. For one, you can always swap out a backend and join multiple APIs together. This means, you could replace an API generated from a DB at any time, even partially, without breaking the client contract. Then, there's also a second abstraction point which has to do with the fact that WunderGraph persists GraphQL Operations by default. It allows you to swap out the entire schema if the Operations stay the same. Both options might not always work but offer good migration paths from a DB generated API away. If you have the resources, it always makes sense to "design" your API. Generating an API is not wrong in many ways. However, for prototyping and simple projects, it might be the right tool to get the job done in a cost sensitive way. To sum it up, generated APIs are not ideal but it really depends on the case. In the end, the customer decides.
- SkyPuncher 5y agoI've dealt with the same issues in nearly every non-GraphQL project I've worked on. If you use types, you need to define those somewhere that each system can understand. In most REST/JSON/whatever, I've worked with this ends up as serializers and deserializers on both ends of the client/server. At it's most basic, you're doing no more work in GraphQL than a "legacy" client-server. ----- I've dabbled with GraphQL in personal projects and I think it far exceeds anything I've worked with in a REST setup. The major issue that I see with GraphQL is it lets you do stupid things incredibly easily. However, this is also it's benefit - a client can grab only and exactly what it needs. The major problems I see with GraphQL is developers using fundamentally poor relational data models.
- andrewingram 5y agoYeah. The unacknowledged assumption being made is that n-definition (much less of a mournful) is inherently a problem. The reality is that each layer of the stack, the definition means a different thing even if the fields are the same _right now_. I’m an advocate of utilities to flatten the layers as an effort-saving measure, but as something to opt into, rather than out of. The layers must always be conceptually there. The reason I don’t like things like Hasura et al is because they flatten by default (your GraphQL server essentially becomes just an ORM for your database), and you’re made to do extra work if you don’t want that.