Live data from Hacker News

Why we decided against GraphQL for local state management

tech.okcupid.com

91–99 of 99 posts

Re: Why we decided against GraphQL for local state management

#91

I'm doing a big Apollo/GraphQL piece for the BBC for a lot of the same reasons OP lists, and have run into pretty much all the same issues with Apollo that OP has. Its rough because Apollo does so much for you, its wonderful, but there are so many sharp edges and pitfalls - from the buggy devtools to the lack of/incorrect docs, major unanswered github issues & constant API breaking changes even on patch/minor version…

I don't understand the problems you guys are running into with Apollo local state. I've been using Apollo rigorously for 2 years now (though not yet upgraded to v3), and my experience is the state is a blessing.

In the past I had to write or figure out my own Redux solutions to store data from queries in the state and now that comes out of the box with Apollo. If I want to manipulate this state locally, I can just do a client.writeQuery in a standard JS function (no resolver bullshit). In the rare event I want purely client-side state, I can use the same method with the @client directive. I've never really needed resolvers as I can contain the logic in my `update` handlers or state manipulation (action) functions that look and behave like standard JS.

Caching is great out of the box. You get all variations you might want (cache-first, cache-only, cache-and-network) and it's very easy to configure. Not sure what problem you ran into. Maybe server-side?

State persistence is a whole different story. I've found it's hard to do well due to Apollo's ROOT_QUERY combining all pieces of the state. It requires almost an all-or-nothing approach or a lot of hacking to get it to work. I've spent a lot of time searching for proper solutions and even built my own, but they've all been insufficient. Considering local storage persistence brings XSS vulnerabilities as well, I've decided to focus my efforts on performance for now which helps both returning and new users.

Personally I love Apollo for its state management and will continue to integrate it in more projects. My biggest gripe at the moment is writing maintainable client-side queries. The code gets quite verbose, especially when you try to do proper (TypeScript) typing without splitting up your code into tiny fragments all over your codebase. And keeping the types in sync with the queries and server-side schema takes a lot of time and effort. I've mostly been thinking about solutions to auto-generate client-side query types, this would increase type-safety as well.

Re: Why we decided against GraphQL for local state management

#92

Earlier quoted context omitted.

> people using it for things when they shouldn't I know people that advocate putting everything in redux. They are quite serious about this. Then you end up with reselect everywhere and the whole goddamn universe is memoized. No one seems to know how React renders (or re-renders), so memoize everything! Yes! That's the ticket. The overuse of Redux and the React hook brain damage stems from the tide finally turning ag…

> Instead of making React's object API better, they choose to make functions worse. I'd be really curious to see how you'd make the object API reusably composable, given that that's one of the basic reasons for hooks existing as they do.

An over emphasis on re-use is what ruined a lot of oop systems also. Maximise reuse, minimise use. It's a trade-off.

Re: Why we decided against GraphQL for local state management

#93
post #87
post #31

Earlier quoted context omitted.

I see what you’re doing there. I also see why you think it’s a good idea. "How the community" uses redux is badly. I guess congrats for reinforcing that at scale. Gives me some more hours to bill when I run across the next ratsnest.

Can you provide some examples of a better way to use redux? The react and redux toolchain is so flexible I'm always interested to see what ways other people come up with to use it.

I have a copy paste dump that I did a few months back to show someone how I was working, happy to pass that along. I wouldn't make claims that the way I'm using things are the best but so far I've been happy with the general approach. There's a simple createActions and a more complex one that handles namespacing.

https://gist.github.com/weeksie/04f41329d0015e2128209df9f9de...

I skimmed the debounce middleware from this guy Nir Kaufman who has some pretty good things to say about front end architecture. Generally with Redux we have a system that can absolutely provide real event-driven CQRS style front end so it seems crazy to ignore that in favor of managing async thunks like it's 2004 and we've all just discovered how to put an XMLHTTPRequest on an onclick handler or something.

Outside of that core.effects file, I put all of the async app logic in custom middleware as well. YMMV but using a framework for replacing const declarations and switch statements is overkill.

The broader point is that if you're going to create utilities like that, it's often worth just rolling your own. When you attach a core part of your application to a framework you've signed up for the ride. I realize it seems like I'm being an asshole to acemarke, who appears to be a perfectly lovely dude, if a little passive-aggressive, but I sincerely feel like pushing libraries for problems that shouldn't require libraries is making our ecosystem worse.

Re: Why we decided against GraphQL for local state management

#94
In backend, most state is nicely stored in a database, in frontend, if you don’t have good foundations for component state state vs app state vs server state, then a lot of things become complicated for a decently sized app.

If you mix everything in one then you have a crazy ball of goo that’s rendering the whole UI tree everytime something small happens. Sure vdom is fast but you’ll still feel it for large apps because generating that vdom may call expensive functions over and over.

Svelte is nice but I haven’t used it for a large project. I do swear by having a good separation of those states. It has served me well for over a decade building UIs in different frameworks.

When component state changes, only that component changes. E.g whether a dropdown is opened.

When appState, changes the whole app tree is vdom diff rendered. Immutability helps here. Props/context are threaded all the way down. E.g the current light/dark theme

ServerState should be subscribed individually by components that need it, and only the components looking at that state render. (E.g List of items from GET call, when you update the item, an update only needs to happen in that one place that keeps its data synced with server)

Re: Why we decided against GraphQL for local state management

#95
post #36

State management is one of the reasons I moved away from React and Vue. You need a lot of machinery and plumbing to do something that should be really simple. MobX is probably the best way I've found to manage reactive state with React, Inferno, etc, but still, it's a huge piece of of software for just this purpose. I first moved to Mithril because it doesn't need reactivity. You solve the same problem than React/Vue…

> should be really simple Ummm... no, state management is pretty much the only hard problem in programming.

[deleted]

Re: Why we decided against GraphQL for local state management

#96
post #71

Earlier quoted context omitted.

> should be really simple Ummm... no, state management is pretty much the only hard problem in programming.

Can you support that? This doesn't seem like anything approaching the truth in the vast majority of web applications (where things like React are typically used). Mostly, in my experience, front end development is made unnecessarily complex by the developers involved.

I see state planning as one of the major barriers to designing a team workflow with idealized Microsoft Access.

Re: Why we decided against GraphQL for local state management

#97
post #36

State management is one of the reasons I moved away from React and Vue. You need a lot of machinery and plumbing to do something that should be really simple. MobX is probably the best way I've found to manage reactive state with React, Inferno, etc, but still, it's a huge piece of of software for just this purpose. I first moved to Mithril because it doesn't need reactivity. You solve the same problem than React/Vue…

That's almost exactly the path I've gone down, and svelte is something I've been seriously researching for a couple months now. I have a nagging problem that keeps coming back to me though. The declarative state model is the holy grail for UI design, but if you try to mix in any form of imperative logic, it all falls apart. All of a sudden you need to understand and plug into poorly documented and opaque component li…

I wrote some about my experiences using Leaflet with Svelte: https://imfeld.dev/writing/leaflet_with_svelte

I found you have to do some extra work to keep track of things to convert from declarative style to Leaflet’s imperative style, but overall I actually had a pretty good experience with it. Feel free to ping me on Twitter (same username) if you have any questions.

Re: Why we decided against GraphQL for local state management

#98
I looked into Apollo for local state years ago, after trying to synchronize remote & local state & running into race conditions, I quickly realized it is better to implement GQL fetching inside something like Redux that is lower level & gives more control over determinism & timings.

The holy grail of "fixing race conditions" and avoiding async bugs is RxJS in my opinion, which is why I am working on what I call a "stream management library", its a state manager where your "state" is represented as RxJS streams https://rx-store.github.io/rx-store/

Re: Why we decided against GraphQL for local state management

#99
The problem with Apollo is that if you use it for server queries, you are basically forced to use it for local state management as well. This is because server state and local state is usually intermingled, so its not practical to have a Redux store for local state and then use the Apollo cache for server state.

This means that Apollo is essentially incompatible with Redux unless you are willing to duplicate the data in the Apollo cache into your Redux store. Such duplication is a waste of resources, and also defeats the point of using Apollo to begin with, since you are circumventing most of its feature and just using it as a plain GraphQL client.

I think Apollo is trying to do too much, and a much better architecture is not to couple your GraphQL query infrastructure to your state management infrastructure. This can be done by using a more low level GraphQL client and then choosing one of the many amazing state management libraries out there in combination. This way your GraphQL client does not dictate your state management layer.

Post reply on HN