
Apollo raises $22M to simplify app development - mostafah
https://blog.apollographql.com/apollo-raises-22-million-to-simplify-app-development-ee30502c81b3
======
tonyjstark
As a user of GraphQL with Apollo since a year, I still don’t see how it
simplifies app development. Actually, having such a huge dependency in the
code feels more like a liability.

Most apps are simple, don’t need to send much data around if you don’t put
3-10 user tracker in, and Rest is just really, really simple for most parts.

In every project I worked so far that used GraphQL, developers tend to not
care about backwards compatibility of APIs because having tons of optional
properties in query responses doesn’t feel nice.

As always, there are exceptions and if it makes sense, sure, go ahead. But be
aware of the dependencies and the magic you get into your project. Oh, and
don’t use it for file upload, that’s just painful.

~~~
TheKidCoder
Couldn't agree more. Apollo has shipped multiple broken releases over the past
year related to having a massive dependency tree - we're migrating away from
their apollo-server system soon.

------
mattbillenstein
I like graphql as technology - I find it just a better way than REST for
building services, and I like that it's just json - simple easy to debug text
responses. I like that there are companies investing in this technology.

But, I don't see how you build a VC funded business out of this - countless
examples of infra companies trying to build a business out of OSS technology
and they always struggle to get paid because they provide so much value for
free.

Docker Inc's struggles come to mind here...

~~~
hwillson
Our approach (at Apollo) for building a VC funded business out of this is:

1\. Build the best GraphQL developer tools we can, focusing on making
developers happy. Make sure those tools are open source, and involve the
GraphQL community as much as possible when building them, to make sure we're
building tools developers actually want to use. With those tools available,
make sure any developer who wants to use them can, for free.

2\. At the same time, build more advanced tooling and sophisticated GraphQL
infrastructure components (that would be costly for an individual organization
to build and maintain themselves), that provide a way for businesses and
organizations to effectively, efficiently, and securely manage their GraphQL
based infrastructure. Give anyone the chance to use these more advanced
tools/components for free up to a certain threshold, to see if they're a good
fit and if they're worth the money. If all signs point to yes, we then start
charging.

Our approach is fairly simple, and has been followed successfully by many
companies before us (a simple plan is a good plan). We've been following this
approach for a while (before this funding came into place), and things have
been going extremely well.

------
djmashko2
(disclaimer: I worked at Meteor/Apollo for about 5 years)

I love the callout to how this is continuing the vision for improving
application development started with Meteor -- it really does feel that way to
me. Apollo, supported by GraphQL is IMO really delivering on the vision of
making a lot of aspects of client-rendered app development much more
straightforward than they have been in the past.

~~~
ben_jones
Honest question, what about GraphQL is straight forward? As a web developer
I've been curious about its hype for a long time but every time I look at its
implementation I balk.

I have a lot of experience with JSON-REST APIs and RPC systems like gRPC and
they both seem clearly superior (especially in tandem with code generators)
where as GraphQL seems like a ton of extra work on the client and server side
for little gain. When asked most developers say its because you can limit
which fields you query, and I have to politely explain to them the existence
of an SQL SELECT query...

~~~
seanalltogether
> When asked most developers say its because you can limit which fields you
> query

For me this is one of the biggest headaches I have with a new app I've been
assigned to. By allowing all fields to be optional depending on the graphql
query, there's no consistency in the objects floating around in your apps data
store. When I reference a Person object in my view that I'm using, will phone
number be there or not, who knows.

Maybe its better when every single page has to request it's own data, but when
the model objects are cached to a data store in an app and shared between
views, things get really dicey.

~~~
atombender
A large part of GraphQL is the idea of tightly coupling queries to code,
declaratively, combined with smart differential logic.

The original web framework for GraphQL was Facebook's Relay, which essentially
lets you declare, in your component, what data you want. Relay stitches
together your query and avoids work by figuring out the difference between
what data the client has (in its cache) and hasn't.

Apollo's React framework is based around the same ideas. You're supposed to
declare the query privately in the component that needs it, and in _principle_
, caching should avoid many unnecessary fetches. For example, if you have:

    
    
      // In component A
      {
        currentUser { id, name }
        topStories { id, title }
      }
    
      // In component B
      {
        currentUser { name }
        favouriteTopics { id, name }
      }
    

then the delta from A to B is { favouriteTopics { id, name } }, and no re-
fetching of currentUser is needed, since it is a subset that merely needs to
be filtered.

(There are of course ways to write queries that will always conflict with each
other, e.g. by applying different parameters such as filters to nested
fields.)

In practice, I'm not sure if Apollo is that smart yet. I _think_ it currently
considers any difference in field selections to be a conflicting change, even
strict subsets, but I could be wrong.

When used outside of React, GraphQL becomes more like SQL:

    
    
      for (const {name} of (await query(gql`{
        users { id, name }
      }`)).users {
        // ...
      }

~~~
lstamour
Theoretically, a smart enough GraphQL front-end could recognize multiple
filters and do some or all of the filtering client-side, or if impossible,
request both from the server. The idea that your client can declare what data
it needs rather than leaving it up to the server is the best part of GraphQL,
the thing that simplified it the most. But it’s hard to do well, right now.
It’s much easier to use code-gen directly to have client and server share
knowledge of what’s needed. HTTP2 push adds an interesting twist though, when
your GraphQL response could actually trigger additional client code and
resources to be sent. Of course this can be done without GraphQL, but you’d
still need a server that’s aware of what data the client will use and how. For
simple APIs or APIs with many clients that behave the same way, GraphQL is
overkill. But even so it’s an interesting alternative to simple REST and
simple state management, and unlike Redux, you can trigger multiple events at
the same time which can be beneficial if processing their state changes at the
same time would lead to a more efficient update. (The Redux alternative is to
add some kind of wrapper event, or an event for each combination of events...)

------
cryptica
Part of me thinks that if Apollo was a good company, they wouldn't need to
keep raising this kind of funding by now. There are plenty of alternatives
which burned a fraction of what Meteor/Apollo has burned to build this.
They're taking funding and attention away from other more deserving projects.

~~~
hwillson
Just to clear this up a bit; Apollo doesn't "need to keep raising this kind of
funding". Both Meteor and Apollo have been making money. What's really
happening here is that both Apollo and its amazing supporters/investors have
witnessed first hand the impact that data graph based technology can have on
the lives of developers and the productivity (and bottom line) of companies.
To help take all of this further, we've decided now is the time to bring more
people on board, so we're substantially growing our team (hence the extra
dollars).

> They're taking funding and attention away from other more deserving
> projects.

I've gotta say, I completely disagree with this statement. Meteor and Apollo
have both helped thousands of developers do amazing things, for free. Yes, I
work for Apollo, but I'll detach for a sec; I can't think of any open source
software company on the planet that deserves this more than they do. I can
tell you first hand that Apollo cares deeply about open source software (OSS
culture is ingrained into the company right from the top), and goes to great
lengths to make developers happy and provide ways for developers to use a
large portion of the things it builds for free - no strings attached. When I
encounter other companies that act like this, I instantly think they should
get anything they need to help themselves flourish and thrive - Apollo is no
different.

~~~
cryptica
>> What's really happening here is that both Apollo and its amazing
supporters/investors have witnessed first hand the impact that data graph
based technology can have on the lives of developers and the productivity (and
bottom line) of companies

It's just a bunch of wealthy people using their money to force their opinions
about software development onto as many developers as possible...

I can guarantee that there exists simpler solutions outside of the GraphQL
bubble that far exceed what can be achieved with Apollo in terms of both
flexibility and productivity. I could share some links if you are genuinely
interested.

------
SirensOfTitan
We really love Apollo and use its open-source software in our GraphQL stack.

With that being said, I really hope Apollo will provide their iOS library some
much needed love soon, or clearly imply they're not developing it anymore.
They've mentioned they're hiring an iOS engineer maybe a year ago? but largely
the repo has gone neglected. I've made some modest improvements for our sake,
but PRs generally go unreviewed forever, so it doesn't seem worth writing the
tests to get my work in a landable state.

~~~
peggyrayzis
Hi from the Apollo team! We hired a mobile engineer who is starting within a
few weeks. Keep your eyes out for lots of exciting improvements to Apollo iOS
soon!

------
RoboTeddy
I like GraphQL a lot — but found that writing mutations involved a ton of
boilerplate. For example, I'd have to keep writing the same key names over and
over again. Anyone else experience this?

~~~
KenanSulayman
You could use input types and reduce the boilerplate to a single parameter,
which you then send as an object in the request variables?

~~~
fernandotakai
yeah that's what i did. inputs also help a bit with code reuse, imho.

------
gregkerzhner
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

~~~
hwillson
Thanks for the feedback, and sorry to hear about these issues! I'll try to
address them below:

> 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.

~~~
gregkerzhner
"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."

You are glossing over the fact that there is a 3rd part, writing a reducer!
This part is the most cumbersome in my opinion.

Lets say you wanted to keep a counter and increment it in your app. With
Redux, you add it to your state, write an "increaseCounter" action, and then
write a reducer. This reducer is just a plain function without any
dependencies. A unit test for this reducer would just test that the count was
updated.

However, with local state management with Apollo, you would either need to 1\.
write an incrementCounter mutation and an incrementCounter reducer. Inside
that reducer, you would have to fetch the current count from the cache, update
that count, and then write the results from the cache. 2\. Just use
`cache.writeQuery` or `cache.writeData`, but in either case, you need to fetch
the current state of the cache, modify it, and then write the object back.

The problem with this is that any time you want to modify state, you need to
always fetch the current state, and then write the state back. This is bad
because

1\. its super repetitive 2\. it tightly binds the code of "how the state
changes" to "how the state is queried and saved"

Overall, this whole approach of having to write a mutation and a reducer for
every state change is annoying and verbose. Redux is just overall a better,
more convenient pattern to incrementally update a piece of state.

We actually thought about adding a Redux layer on top of Apollo, so that we
would just have a single "Redux" mutation that fetches the current state,
passes it to a reducer, and then saves the transformed state in the cache to
avoid all this fetching and saving, but then were afraid of potential
performance issues of homerolling our own Redux, and went with actual Redux
instead.

------
thatguyagain
I work a little bit with a graphql backend API and apollo in the front, and I
still have no idea why this is better than a rest API and regular fetches in
the front. I feel like we are moving backwards. Way more code to type out
which fields you want back, and the same in the back + the actual
resolvers/mutations. I really don’t get any of this..

------
oblib
How does this compare to using CouchDB/PouchDB?

(maybe it doesn't, but at first glance it looks similar in a lot of ways to
me)

~~~
mrgordon
CouchDB is a document store style database. GraphQL is more focused on the API
layer (how do I query any underlying data sources for exactly the data I need)
instead of tying you into one particular database. So, in theory, some of your
GraphQL objects might live in CouchDB but others might live in PostgreSQL or a
file store.

~~~
oblib
Ok, that's pretty cool

Thank you for the insight!

------
baybal2
I found that despite the name, making something like a graph crawler is kinda
hard in graph ql because you have to write "a new schema for discovery of
schema" (all is made kinda hard to query the schema itself)

------
tkainrad
Interesting article. However, I disagree with the premise. Data management is
certainly not the hardest problem in app development.

Everybody knows there are exactly three hard problems in software development:

1\. Naming Conventions

2\. Off-by-one-Errors

------
neya
I was a huge proponent of GraphQL and used it for many clients. For me, it
solved a specific need - I can write an API backend that is scalable across
clients (Web, iOS, Android). However, having said that, I have made the
mistake of using GraphQL for projects that only have web interfaces with
somewhat complex querying (but with vague ideas of expanding to apps later).
It wasted so much of my time that I ditched the project halfway and re-wrote
everything using normal CRUD interfaces. I use Phoenix + LiveView now, and
it's truly a god send to write code without having to touch any Javascript.
Not only are my interfaces way lighter, but they also feel very natural and I
get server rendered error messages out of the box without having to parse them
on my frontend.

GraphQL is a rabbit hole. Don't use it unless absolutely necessary or you have
a small to mid-sized team for large scale projects. Atleast on Phoenix/Elixir
side of things, it's just not worth the effort - you need to write resolvers
apart from your schema/models, handle changeset errors in the frontend (which
there is no way to deal with directly as of this comment) and if you're
working with VueJS, then good luck. My package.json is so bloated that I am
starting to feel it's all just a pack of cards. I can't stress enough how much
valuable developer time I wasted getting all these bits and pieces working
together. Usually, you can't use one because the other one is outdated, or has
some weird Github issue you now need to address. And then that causes another
probelm..and another one..[the rabbit hole goes deep]

    
    
        "@babel/core": "^7.0.0",
        "@babel/plugin-syntax-dynamic-import": "^7.2.0",
        "@babel/preset-env": "^7.0.0",
        "apollo-absinthe-upload-link": "^1.5.0",
        "apollo-cache-inmemory": "^1.6.1",
        "apollo-client": "^2.6.1",
        "apollo-link": "^1.2.11",
        "apollo-link-context": "^1.0.17",
        "babel-loader": "^8.0.0",
        "babel-preset-env": "^1.7.0",
        "coffee-loader": "^0.9.0",
        "copy-webpack-plugin": "^4.5.0",
        "css-loader": "^2.1.1",
        "file-loader": "^3.0.1",
        "graphql": "^14.3.1",
        "graphql-tag": "^2.10.1",
        "mini-css-extract-plugin": "^0.4.0",
        "node-sass": "^4.12.0",
        "optimize-css-assets-webpack-plugin": "^5.0.1",
        "resolve-url-loader": "^3.1.0",
        "sass-loader": "^7.1.0",
        "script-loader": "^0.7.2",
        "style-loader": "^0.23.1",
        "uglifyjs-webpack-plugin": "^1.2.4",
        "vue-apollo": "^3.0.0-beta.30",
        "vue-loader": "^15.7.0",
        "vue-template-compiler": "^2.6.10",
    

When DHH ranted about these, I never believed him and I always thought he was
not upto par with JS frameworks. But turns out, everything he said was true.
Turns out, you don't need GraphQL at all for most use cases when you can
simply get away with something like Tubrolinks or LiveView.

~~~
rozenmd
Not gonna lie, that's a pretty lean package.json file...

~~~
neya
I extracted out just the GraphQL related bits

~~~
kabes
like sass-loader? A big part of the list are dev utils that are not related to
graphql at all...

------
marknadal
This is awesome, congrats!

Does this mean Meteor is dead?

Also, the end paragraph mentions some cloud-based graph management system. Is
there any chance they could do a decentralized graph management system
(something like [https://github.com/brysgo/graphql-
gun](https://github.com/brysgo/graphql-gun) ) instead of some centralized
solution?

I don't want my GraphQL data getting locked in to some vendor. Any reason why
I shouldn't worry about this? Thanks!

~~~
JMTQp8lwXL
Meteor, as a framework, was solid for its time. I don't think they could've
envisioned how much the JavaScript ecosystem would change after its launch. It
tried to solve a great deal of problems that ultimately were solved in
smaller, more focused libraries.

~~~
bnjmn
Thanks, this is a good take.

I would add: now it's everyone else's job to make those smaller, more focused
libraries work together. The time wasted is unfathomable, but the blame for
misconfiguration now falls on individual developers, rather than monolithic
frameworks. Progress?

~~~
JMTQp8lwXL
At least in terms of tooling, you see things like create-react-app, vue-cli,
etc. These toolkits, and their accompanying CLIs, abstract away configuration
of babel, webpack, etc.

These are good, but if you need to customize further, you interface with the
toolkit (which only allows you to go so far), or you eject entirely.

Many people think it's time wasted to really understand how to setup and use
(individually) webpack and babel and friends. I disagree because if you ever
do need to dig in to these tools, since you've used them individually, you
understand what you need to change.

If you eject from a toolkit but don't understand the underlying tools, you
could be up a creek without a paddle. So you can certainly make things
simpler, but you can't replace having the experience and understanding of what
each individual tool does, and how to interface with it.

I would say the ecosystem changes, in aggregate, are probably a loss for new
programmers. You have a much wider API surface to be aware of when using all
the tools and how to integrate them. But for a senior front end engineer, it's
unlocked the ability to have very fine grained control over the bundles you're
creating.

~~~
indalo
The power comes in two fronts. The ease that the cli tools you mentioned to
help you gather a solid baseline of these smaller packages, and then, giving
you the ability to decompose the features into interchangeable parts by
ejecting or just by virtue of how small the packages are. The problem with
monolithic frameworks in my opinion lies with the second part, they develop to
he opinionated and for valid reasons, but sometimes that create really intense
friction when changes need to happen in particular ways.

