Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Additional graph pain points I'd add:

Reliability:

* Not null fields in a distributed system are a lie. Clients write code assuming something is not null, so a query that fetches data from N sub systems breaks the entire page when one of them fails.

Performance:

* People say you only need to fetch just what the page wants but in practice clients create re-usable fragments for every object in the system and use it everywhere. Any time a new field is added, every api call fetches that new field adding latency everywhere

* clients are unaware of the underlying topology and add fields that are usually harmless but have bad tail latencies.

* The completely generic nature of the API means the backend can't optimize performance for a specific page. E.g. if one API has nasty tails, but it's not that important for this page, the backend could time it out at some reasonable value instead of holding up the entire request



* Not null fields in a distributed system are a lie

If something is null that's not supposed to be null, then the entire operation should be called into question. It's probably not safe to proceed so it's a good thing he entire page breaks, you don't want users to continue based on wrong information. If you define something in the schema that it's possible that it's null, but then the frontend dev ignores the fact that it can be null, why is it GraphQL's fault then that the page breaks?

* clients create re-usable fragments for every object

As a frontend developer I don't know why you would do that, but if your frontend devs are doing that then yes they are doing it wrong... However switching to REST with statically defined endpoints doesn't solve the over/underfetching problem, but as backend developer you do get to gatekeep that aspect. So yeah the devs should really be just doing it right.


The problem with not null is people classify them from a domain perspective and not from a distributed systems perspective where basically everything can be null but only some fields mean rendering the page is impossible. It also depends page by page what fields make it unrenderable


In my experience, nothing other than nullable DB fields should be nullable in the GQL schema. Everything else like inter-service problems, auth problems, etc, should be modeled as “result boxes” via union types (somewhat equivalent to Maybe/Optional types). This lets your schema model possible failure cases via strong types without ambiguity and results in resilient front-end code.

Note that the error types added to the union should only be as granular as relevant to the client. Most places will be just Foo | FooNotFound | FooError because your UI doesn’t care why there was an error and you don’t want to unnecessarily leak backend info when it’s not relevant.

I wish this was more strongly recommended in the GQL org docs, because so many people learn it the hard way and migrating is not easy.


About nulls: you're right, but because of authorization, everything can be null - if you don't have access to something, we need to remove it from the result (instead of just throwing an error, as you may still get enough information to do what you need to do) - and that will always be a fetcher error in GraphQL if the field was non-nullable. And because you shouldn't really know or care beforehand which fields may be "hidden" from the end user due to authorization, you need to make everything nullable or risk making a breaking change later.


Same thing in sql. Non null guarantees are great until you do a left join.


> clients create re-usable fragments for every object in the system and use it everywhere

I quite like Relay's pattern where components define their data requirements, and this is passed up the component tree to some query at the root. Avoids a situation where the query defined at the root asks for unnecessary fields because it's so far away from where the data is actually required.

https://relay.dev/docs/principles-and-architecture/thinking-...


GraphQL really did not handle fragments nicely. Why do you have to create subclasses for each use case and not just put your desired field name…




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: