
The GraphQL stack: How everything fits together - quodestabsurdum
https://dev-blog.apollodata.com/the-graphql-stack-how-everything-fits-together-35f8bf34f841
======
jondubois
My main concern with GraphQL is access control. What happens if the user
doesn't have access to part of the requested data (a subtree)... Will the
GraphQL engine return an incomplete result, an inline error or will the whole
query fail? What if you only want to allow showing specific fields of a
resource; for example when a user requests for another user's account details,
we need a way to block them from getting certain fields like passwords or keys
that might be attached to the account.

How does this access control play with cache? What happens when the access
control rules change?

A while ago, I wrote a real-time REST-based plugin which solves all the
problems and I use it in production, it's much simpler than GraphQL. See
[https://github.com/SocketCluster/sc-sample-
inventory](https://github.com/SocketCluster/sc-sample-inventory)

I'm surprised that more libraries aren't following the REST-based model.

~~~
nijynot
The solution for authorization/access control is to use "Dataloader" [1] which
is also made by Facebook. You write a single source of truth for how
authorization is handled, and make sure that graphql resolves with this
source.

Dataloader is not as well known as GraphQL, but crucial for complex
authorization systems imo. It also has a bunch of other features like batching
and caching which makes your life easier when opting for this solution.

[1]:
[https://github.com/facebook/dataloader](https://github.com/facebook/dataloader)

~~~
mxstbr
I've only ever seen DataLoader used for batching database queries, how do you
create a single source of truth for authorization with it? Do you have a code
snippet somewhere?

~~~
nijynot
Check out this article [1] (or video) on Dan Schafer's talk, on how they use
Dataloader and GraphQL internally at Facebook. Covers most of it.

To summarize, they create a class for each GraphQLType which has their own
"gen" function such that it is the only way to generate data. This way you get
a single source of truth.

There's also a video of Lee Byron going through Dataloader's source code which
was pretty fun to watch.

[1]: [https://dev-blog.apollodata.com/graphql-at-facebook-by-
dan-s...](https://dev-blog.apollodata.com/graphql-at-facebook-by-dan-
schafer-38d65ef075af)

------
dmitriid
> GraphQL knows all of the data requirements for a UI component up front,
> enabling new types of server functionality. For example, batching and
> caching underlying API calls within a single query becomes easy with
> GraphQL.

And immediately after that the article spends two pages of text explaining how
insanely complex the "becomes easy with GraphQL" really is, and offers no
actual details on the "easy" part.

Oh, your client has to be cache aware. Oh, and there has to be a gateway
that's cache aware, and schema aware, and has to cache all responses... And
invalidate them... But there are no tools yet. And then the graphql server
should be cache aware. Oh, and your database layer should also cache all
responses.

Caching is a hard problem, and there's nothing in GraphQL to make it easier.
Heck, exclusively relying on POST requests they deliberately remove the most
obvious and the easiest part of the equation.

I love how the every next part, starts ,with a sentence that shows how complex
caching with GraphQL is (emphasis mine):

> With GraphQL, frontend developers have the capability to work with data in a
> much more fine-grained way than with endpoint-based systems. _They can ask
> for exactly what they need, and skip fields they aren’t going to use_.

I would love to see an explanation how GraphQL makes caching for this easy.

> Schema stitching is a simple concept: GraphQL makes it easy to combine
> multiple APIs into one, so you can implement different parts of your schema
> as independent services. These services can be deployed separately, written
> in different languages, or maybe even owned by different organizations.

It's called REST APIs and we've known how to do them since 2001.

~~~
Cthulhu_
> It's called REST APIs and we've known how to do them since 2001.

The aim of GraphQL insofar as I understand it is that instead of having to
develop two things (a front-end and a back-end REST API that talks to your
database or other services), you need just one (a front-end that talks to
GraphQL). Mind you, graphQL becomes the back-end-for-front-end then, and will
still need a lot of work. The main point is that with GraphQL you'll only need
one for all of your apps, while traditionally you'd write one REST API for
each client.

~~~
kazagistar
> you'll only need one for all of your apps,

So where are my clients for statically typed languages? I looked into GraphQL
and promptly dropped it cause I couldn't seem to call into it from Java in any
sensible way. If all your "apps" are javascript, maybe this is true, but that
hardly makes it a universal technology.

~~~
lomereiter
It could have better documentation but here's the Java client for Android:
[https://github.com/apollographql/apollo-
android](https://github.com/apollographql/apollo-android) There's also a Swift
client available:
[https://www.apollographql.com/docs/ios/](https://www.apollographql.com/docs/ios/)

~~~
kazagistar
That looks pretty decent indeed, and makes me a lot more hopeful about the
promises of GraphQL, but it sounds like its an Android specific
implementation, rather then something I could actually use for JVM service-to-
service communication.

------
boubiyeah
GraphQL is above all, just an optimization. It optimizes the amount of bytes
sent over the network.

I'm very happy with REST APIs (maturity level 2/3) and see no reason to change
as we've never had performance issues. Most companies are not Facebook with 1
billion customers.

The fact that clients can compose their own queries brings nothing new, as you
still have to allow these capabilities on your server, just like with REST;
you have to code against all the possible variations (primary resources,
filters, sorts, etc) and optimize the DB/remote reads. So no, the users have
no more freedom, the server remains the limiting factor.

The way it lets you compose queries is nice for developers, but you can very
easily do that with a single aggregation REST endpoint too, provided you have
resource links in your responses (which also makes it nice to use with human
tools like POSTman) and you can still cache the individual REST responses with
Varnish, etc.

Doing Subscriptions or mutations over GrapQL brings very little benefits. In
fact, it's even dangerous as most system shouldn't allow multiple mutations
per request.

The whole "just cache it on the client" is a big joke and many people seem to
underestimate getting caching right. The default in Relay used to be "cache
forever", this can't be serious. You could only do that if the current user
was the only person able to modify the data or if you could guarantee a
perfect synchronization with the server via continuous events and that's
actually pretty hard to get right and generally a big investment. In practise,
most apps/sites don't work like that.

I'm not sure what that leaves? "Free" barebone documentation? You can have
that too with a good type system (e.g scala's) albeit with a lot more work but
with a much nicer type system / expressivity.

I mean, I get why it's popular, but the thing's totally blown out of
proportion.

~~~
Touche
Can't upvote this enough. From what I've read it sounds like GraphQL solves a
problem at Facebook where they have so many people working on related data at
the same time that they started seeing duplicate API endpoints, and duplicate
requests for the same data from different parts of the team. GraphQL provides
a chokepoint to prevent that from occurring.

Makes total sense at that scale. Why startups are adopting this _without_ that
sort of problem, I have no idea. Because the query syntax is pretty?

~~~
CodesInChaos
A huge selling point for me is that the client explicitly enumerating all
fields they're interested in allows targeted deprecation warnings and finely
grained usage statistics.

~~~
Touche
Another thing that sounds worthy when working on gigantic teams and less so
when at a startup / small company.

~~~
abritinthebay
Chose the right tech early and you’ll have less growth pain.

I can’t tell you the number of startups I’ve seen that spend time thrashing on
their REST APIs who would be better off using GraphQL as the consumable
interface.

Would have made many companies supplication development go WAY smoother

~~~
boubiyeah
You're saying "graphQL is always better than REST for new/small companies";
that's simply not true. It's a tradeoff. Same with (g)RPC.

Just like you wouldn't buy and install 20 powerful servers to run kafka on day
1 just in case your startup meet huge success in 2 years.

~~~
abritinthebay
I did not say that at all, I urge you to re-read what I wrote.

------
djmashko2
(Author of the post here)

If you aren't yet familiar with GraphQL and the problems it solves, it might
be better to watch the talk on YouTube, since it includes much more of an
introduction from the start, plus more color and detail:
[https://www.youtube.com/watch?v=ykp6Za9rM58](https://www.youtube.com/watch?v=ykp6Za9rM58)

The blog post summary glosses over the introduction and focuses on what a
GraphQL-familiar audience will find new, so it's all in the context of the
current GraphQL community.

You can also catch up on some of the tools and benefits, and see some case
studies from people using GraphQL in production, on our Explore GraphQL site:
[https://www.graphql.com/](https://www.graphql.com/)

------
d3ckard
Can anybody explain to me how it's solving any problems? The way I see it they
only move the responsibility to combine data from client to server. At the
same time, you now don't just expose a couple of endpoints, you need to
support a query language, which seems to impose much more effort in things
like authorization. I admit I don't see the benefit.

~~~
sorenbs
Moving the responsibility of combining data to the server is a huge advantage
for many organisations. It allows application developers to move much quicker
and provides a common data access layer for all applications. It sounds to me
like you are over-indexing on the burden placed on the backend developer in
your evaluation and not considering the whole picture.

From my experience, the biggest advantage of GraphQL is that having a well
defined standard allows the community to build advanced tooling such as
[https://github.com/graphcool/graphql-
playground](https://github.com/graphcool/graphql-playground) by Graphcool and
all the cool stuff Sashko is talking about in this presentation.

~~~
d3ckard
That I understand.

The problem is that on the way you basically reduce your server to the thin
layer over DB. Exposing querying API means that you significantly lose control
over what, where and how you provide from the server.

We are currently considering using GraphQL in current project and I took a
long look at both the standard and library (Absinthe for Elixir). It looks
terrible to me. Basically you need to provide yet another layer, supporting
mostly generic operations. If your action is more then CRUD, you still need a
REST API.

Moreover, you slowly lose control on what can be changed and where, your
frontend basically eating logic, but unlikely to be working on it's own.

I understand that it helps when you have records with multiple associations
and you want to increase performance and not load everything everywhere, but
the cost appears to be huge in terms of maintenance. I totally get why FB is
doing it, but it seriously worries me that they market it as an successor to
REST, instead of an alternative with such-and-such tradeoffs.

~~~
yen223
We've used GraphQL in production for about a year now, alongside some legacy
rest APIs. It's a lot easier to maintain the GraphQL endpoint, like it's not
even close.

GraphQL's secret weapon is the static type definition. We can safely alter
fields in the backend, and be notified _at compile-time_ if client-side code
is about to break as a result of those changes. We don't have the same
guarantees with the rest api, which is the only reason they're still around at
all - it's so hard to make changes if you have little idea which client-side
code depends on which field.

~~~
boubiyeah
Are you talking about a single client and its server? (a.k.a backend-for-
frontend). This is not a hard problem to solve when you share a single
programming language, with or without graphql.

Because you can't possibly now what your API consumers use on their side.

~~~
yen223
> Because you can't possibly now what your API consumers use on their side.

Not only do we know exactly what fields the API consumers are using, we also
know the types they're expecting. We can make schema refactors fairly safely.
That goes a long way towards making the codebase less brittle as a whole

------
DigitalJack
I'm an admitted dumbo about this stuff. Here's what it looked like from that
point of view:

Hey cool, a new nice looking common query language that can do neat
composition of results. Perfect, I've been wanting to break free of the SQL
box since forever.

Wait, what? You have to write SQL queries for everything still? So you define
types, and have to write SQL queries for those types, and graphQL gives you
some composition on top of that?

Seems kind of redundant. Like wrapping your own christmas present.

But then I realize I'm thinking from the perspective of a one/two person team.
Perhaps the real value of this comes from very decoupled consumers.

~~~
djmashko2
You're in luck, there are libraries that can do it for you!
[https://github.com/stems/join-monster](https://github.com/stems/join-monster)

And even a system that generates your whole schema:
[https://github.com/postgraphql/postgraphql](https://github.com/postgraphql/postgraphql)

Plus, the Graphcool framework allows you to bring your own DB:
[https://github.com/graphcool/framework](https://github.com/graphcool/framework)

~~~
DigitalJack
Holy crap, that's awesome, thanks!

------
voidr
The thing that bothers me about GraphQL is that it adds multiple layers that I
have to debug if something goes wrong.

I have an app that displays a hello world from the server, and it's not
displaying, where is the problem? Is it in my UI code? is it in Relay? is it
in the server side part of GraphQL? is it in my actual API that returns hello
world?

If I'm using a good MVC framework on a the backend, I most likely model my
schema already in some way, having to duplicate that same information for
GraphQL feels wrong.

GraphQL fixes the over-fetching problem, however it requires me to implement a
server side component for this, that makes me think if it would be less effort
to just refine the server side endpoints and not having to support an extra
service.

------
Svenstaro
Has anybody found a way to combine GraphQL and REST in a common API? I've
searched but so far found no idiomatic ways to accomplish that.

The reason I need REST in addition to GraphQL is that there are sometimes
oddball cases where only GraphQL is a poor fit or where compatibility with
older clients that I can't modify has to be ensured.

Also, is there a good way to do file upload of big files with GraphQL
nowadays?

~~~
atomashpolskiy
We're developing a REST framework, which lets the client to shape response on
a predetermined and constrained set of endpoints on the server. The client can
include/exclude parts of the data (attributes and relationships), set filters
and request aggregation. You may take a look:
[http://linkrest.io](http://linkrest.io)

~~~
kyberias
So you're basically cloning OData, aren't you?

------
marknadal
You can get some of these benefits for free and today by using
[https://github.com/brysgo/graphql-gun](https://github.com/brysgo/graphql-gun)
(disclaimer: I did not write this, but I am the author of the library it
depends upon).

1\. For instance, caching also happens on the client. This means if you reload
the page, your GraphQL query will pull immediately from localStorage!

2\. And then, quite important, it will be backfilled by the server with any
new updates, including realtime updates that happen from other peers while the
user is still using your app.

Great work on the tracing and schema support pieces! Those are certainly handy
features.

------
Hendrixer
I'd love to see some examples of a proper GraphQL gateway that consumes the
cache control

~~~
djmashko2
We've got one here you can try out, and I hope people build more!

[https://www.apollographql.com/engine/](https://www.apollographql.com/engine/)

(Disclaimer: I work on Engine)

~~~
Hendrixer
Oh I know about engine. I'm talking an open source one

------
stuartaxelowen
Why graphql instead of SQL with proper access control?

~~~
elnygren
This question does not make much sense: a GraphQL API can an often is
implemented with SQL !

You could ask: why graphql instead of RESTful?

~~~
guelo
Of course it makes sense. They're both query languages, right? Why is

    
    
       { project(name: "GraphQL") { tagline } }
    

Better than

    
    
      select tagline from project where name = "GraphQL"
    

Especially if the GraphQL server is just an intermediary later that ends up
being translated to SQL anyway.

That real answer to the parent's question is that most people don't have
confidence in SQL servers's access controls.

~~~
elnygren
If you're proposing that web servers should not exist and we should just
expose the SQL DB via HTTP: what about when you don't have all of your data in
a single database?

What if I want/need Cassandra, ElasticSearch or MongoDB? An SQL DB is just one
place where you have data and there are very valid reasons for using other
solutions.

In fact, some people might argue that you want to do everything with event
sourcing / kappa and use Kafka + specialised data stores.

GraphQL fits this universe perfectly. It also fits the one where you only use
a single SQL DB since a GraphQL query translates quite nicely to SQL with
minimal amount of code in between.

~~~
dragonwriter
Using SQL as a query language doesn't limit your choice of backend data
source(s) any more than using GraphQL does.

------
timsuchanek
For anyone interested how a concrete implementation of this architecture can
look like, we created an example project that includes the Gateway pattern
with schema stitching and powerful resolver middlewares:
[https://github.com/graphcool/graphql-
boilerplate](https://github.com/graphcool/graphql-boilerplate)

------
sean_lynch
I'm interested in GraphQL but definitely haven't been following closely.

This seems to be a marketing video for Apollo's products. Is that what most
GraphQL stacks look like in production these days?

------
kyberias
How is this different, better, worse than OData?

[http://www.odata.org/](http://www.odata.org/)

~~~
djmashko2
Jonas Helfer gave a talk about this:
[https://www.youtube.com/watch?v=coU6OmISOBM](https://www.youtube.com/watch?v=coU6OmISOBM)

~~~
kyberias
That wasn't very objective or thorough comparison. But I certainly learned
that the guy didn't like OData.

------
cohen900
That's sounds good..!

