Apollo Client 2.5 for GraphQL Announced
blog.apollographql.com
blog.apollographql.com
To go from mature backend frameworks with autogenerated REST APIs to manually writing a lot of boilerplate code just to get a _basic_ GraphQL API running is frustrating. Part of the blame goes to the marketing of GraphQL. For example, the tagline on graphql.org is "Describe your data | Ask for what you want | Get predictable results". That's all well and good, but it leaves out the large majority of the work you have to do. This describes the schema, the query, and the result; but what about all the resolver code you have to write? That's the painful part of the whole process, especially when you get to the point of writing field-level resolvers and integrating child objects (DataLoader, etc.).
And then on the frontend, Apollo is preaching for us to write client-side queries AND client-side resolvers to fetch data that's _already in the cache_. All of this just to read, for example, a single primitive value? This is just too much.
You can still use Apollo as a client side solution for the above. The client side resolvers Apollo speaks about is for client-side data. This is if you optionally want to use the same patterns on the front end to manage your local state. But it's totally optional. You can use Apollo + Redux or Apollo + setState or Apollo + MobX or Apollo + useReducer or whatever.
There's a reason DB schemas are considered a feature, rather than a burden, by most.
I don't think backend services with mature REST APIs are the problem; rather, it's fetching and aggregating their data on the frontend that's cumbersome. With the complexity of modern apps, developers have to write a considerable amount of data fetching code to build out new features. They have to fetch data from multiple REST APIs, filter down that data, aggregate it, cache it, and account for loading and error states. Writing all of this state management code by hand slows developers down and leads to bugs.
Apollo aims to solve this problem by unifying around one way to query all of your app's local and remote data. This reduces state management code considerably since Apollo takes care of fetching, tracking loading and error states, and caching your data. For simple primitive values that aren't shared among multiple components, I totally agree that Apollo is overkill and would recommend seeing how far you can get with React state instead. For local data that's shared among many components, like device API results or global boolean flags that you would put in a Redux store, Apollo shines because it allows you to specify all of your data requirements declaratively in one query.
While you do have to integrate a new data graph layer into your stack to take advantage of all the state management benefits, you don't have to migrate your REST APIs. Apollo Server has a data source plugin [1] that simplifies hooking a GraphQL server up to existing REST APIs, including a cache that eliminates the need for DataLoader in most cases.
I hope this helped to clear up any misconceptions. Happy to answer any other questions you might have!
[1] https://www.apollographql.com/docs/apollo-server/features/da...
It is insane how many silent failure modes the Apollo cache has. Performance and ability to estimate work (predictability) went through the roof since then. It's just way overcomplicating things to do state management this way - Apollo is a lovely GQL client otherwise.
I may do a write-up on this one day, as a cautionary tale. It boggles the mind that this is being pushed so hard as an ultimate solution to state management - nice in theory but awful in practice.
How are you integrating GQL in your Redux code? Do you still use Apollo Query/Mutation components? Do you use Redux in lieu of the Apollo cache? How do you deal with the slight mismatch of denormalized GQL data with a normalized Redux store?
I understand the problem that the Apollo cache is solving, and I feel like I do a lot of low value handwritten code when I use Redux instead--but the visibility and transparency of Redux still feels worth it?
I think leaning too heavily into apollo-link-state is going to draw the same boilerplate complaints of Redux. The amount of client code generation needed, plus all the schema details bleeding into your code (__typename)... doesn't feel like we are at the "solution" yet.
Just a few of my rambling thoughts. Kudos to the Apollo team for continuing to push the community forward. These are hard problems and we won't solve them without people trying to innovate.
1) Clear types and structs that are shared between client and server means that both can generate models based on a common set of data specs
2) Clients can have some autonomy in what data they choose to fetch. This is easier said than done but models may be set up to allow joins on datasets for custom model trees and reduced payload size by limiting the fields returned.
GraphQL is also typed, and has some really great developer tooling as a result. It’s usually really easy to learn about a data source by just exploring in graphiql with ctrl+space autocomplete. Eg, check out github’s API: https://developer.github.com/v4/explorer/
Other benefits are that you don't need to write multiple endpoints to serve condensed responses, since the client declares exactly what data it needs in the request. So a mobile client that only needs a fraction of the data of a web client can get back exactly what it needs, and there's no need for the backend to create separate REST endpoints or params for managing that. It's part of the spec.