|
I think GraphQL is pretty cool, but my experience with Apollo is mostly negative. The query and mutation components for example - on the surface, they seem pretty useful, however, in reality, its a bad idea to have your view layer directly making API calls - those should be in some other module thats lower level, away from the view and easier to test. But instead, people use these query components everywhere, and all of the sudden, all the app's logic is weaved into the view and very hard to unit test. Apollo's local state tools are bad in my opinion as well. It might work OK if you just want to keep a few global flags, but anything more, and it gets really verbose. Especially if you want to update state based on current state, you have to first manually fetch the current state, then update it, then save that object back, every time. On top of this, its often necessary to write mutations just to update local state, which are written as GraphQL strings - one mistake in this syntax and you can be stuck trying to debug it for a while. How any of that is easier than just having Redux I still don't understand. Overall, Apollo feels like a worse version of Angular.js - an app framework thats trying to do way too much. If your app just made basic GET requests and had no other logic, I could see how Apollo could be useful (but why have a framework at all in this case?) However, if you have complex logic or local state, Apollo quickly becomes and opinionated, unwieldy piece of junk |
> in reality, its a bad idea to have your view layer directly making API calls - those should be in some other module thats lower level, away from the view and easier to test.
Apollo doesn't force you to cram everything into your view layer. If you want full control over how your interact with your GraphQL backend, you can wrap "Apollo Client" in whatever layer you want. If you're using a view layer integration like "React Apollo", we try to help reduce some of the extra layer boilerplate that can come up, when integrating your view layer with other controller, model, business, etc. layers. Again though, none of this is mandatory, and it's important to understand that components in "React Apollo" aren't directly making API calls. Query, Mutation and Subscription components are just React components, that communicate with Apollo Client behind the scenes. Here, "Apollo Client" is the lower level module that you're referring to, that then takes care of API calls. As for testing, you can (and should if possible) test all parts of your application, be it view layer or lower level API integration points. We provide tools to help unit test React Apollo components with mock/fake data (that can be integrated with any popular React testing library), and there are lots of great ways to unit/integration test Apollo Client (and its associated libraries).
> But instead, people use these query components everywhere, and all of the sudden, the view balloons with logic like parameter validation, error handling, etc... Everything is weaved into the view and very hard to unit test.
React gives you a toolset to work with and manage components. Can you build an application that gets out of control using React? Absolutely. Apollo gives you a toolset that can be used to work with data. Can you build an application that gets out of control with Apollo? Most definitely. Just like the React team, we've taken a lot of steps to help developers avoid these application design pitfalls. We spend a lot of time working on our docs, routinely blog about best practices, and help developers whenever/wherever we can, through various social channels, meetups, conferences, etc. That being said, we've worked side by side with hundreds of developers who are using Apollo happily and productively, and if anything, have found that Apollo's view layer integration has helped them get their countless view layer data integration points under control (and made things easier to test).
> Apollo's local state tools are bad in my opinion as well. To update any state, you have to constantly fetch the current state and then make a modification.
This isn't accurate. Actually, in most cases saving and updating local state is as easy as just running a query/mutation - everything happens for you seamlessly. Apollo Client's local state capabilities have changed quite a bit as of version 2.5, so give a newer version a try (and see the updated docs) to see if that helps.
> This feels a lot more cumbersome than just having redux and reducers.
Redux can definitely come in handy, but it has its strengths and weaknesses (like all tech). One of the core tenants of Apollo Client's local state handling is that it knows how to work with GraphQL out of the box. This means AC's local state handling can be used to do all sorts of great things, that would require more work to accomplish with something like Redux. Things like working with a specialized cache that normalizes GraphQL query responses to speed up cache reading/writing, know how to merge local state with results returned from remote queries so applications get everything they need from local and remote after running a single query, replicate remote GraphQL resolver functionality locally to inject advanced data management techniques on the client side, etc.
> Overall, Apollo feels like a worse version of Angular.js - an app framework thats trying to do way too much. If your app just made basic GET requests and had no other logic, I could see how Apollo could be useful. But anything more complex, and the code becomes a weaving, untestable mess.
Some of the biggest companies on the planet (with amazingly complex applications and systems) are using Apollo and loving it. That being said, we're always striving to do better and welcome constructive feedback like yours. Please consider opening issues in any of our Github repos with your problems and suggestions regarding how we can help make things better.