
Apollo Server 1.0  – GraphQL Server for Node.js Frameworks - michaelsbradley
https://dev-blog.apollodata.com/apollo-server-1-0-a-graphql-server-for-all-node-js-frameworks-2b37d3342f7c
======
throwaway2016a
I never quite understood Apollo. I've written GraphQL servers using just the
Node.js GraphQL implementation and they haven't been much code. Barely more
boilerplate than the Apollo example given.

I'll have to dive into the code myself when I have some free time but can
anyone explain to me what value this adds specifically?

I am assuming it does add value and I'm just not seeing it.

~~~
batmansmk
From the doc:

Comparison with express-graphql

\- express-graphql works with Express and Connect, Apollo Server supports
Express, Connect, Hapi, Koa and Restify.

\- Compared to express-graphql, Apollo Server has a simpler interface and
supports exactly one way of passing queries.

\- Apollo Server separates serving GraphiQL (an in-browser IDE for exploring
GraphQL) from responding to GraphQL requests.

\- express-graphql contains code for parsing HTTP request bodies, Apollo
Server leaves that to standard packages like body-parser.

\- Apollo Server includes an OperationStore to easily manage whitelisting.

\- Apollo Server is built with TypeScript.

~~~
throwaway2016a
Thank you for digging that up. You don't need to use express-graphql to use
graphql on a server so that comparison is only meaningful if you already use a
wrapper... I'm was curious why a wrapper is even needed. The base GraphQL.js
library is not complicated.

The Apollo team member himself even said the wrapper is "thin."

------
cutler
So we now have React/Webpack + Redux + Apollo + GraphQL + Node + Pogstgres
where once we had Rails/PHP/Django + Postgres. Someone hit me over the head
because I don't get how all this is progress. There's no way I can teach web
development to a beginner if there are so many layers between request and
response.

~~~
cle
I don't really understand this criticism. If your web app is simple/static
enough, then by all means use Rails. Everything will be simpler. But there are
an entire class of applications that can't be built with that stack.

~~~
parasubvert
That's a very bold statement: "can't be built with that stack".

A large portion of apps aren't built with Node or React, they're built with,
say, Rails, Java/Spring or .NET backends and a front end framework like
Angular.

I get the theory behind React, the reality is that it is often a complete
mess.

------
danr4
Couldn't find if Apollo solves the database round trips issue with GraphQL
(the joins/n+1 problem). Can anybody shed a light on it?

~~~
sorenbs
There are basically two approaches to this issue:

0) Do nothing

If you are just prototyping, you should do the simplest thing that could
possibly work. (But this is not a real solution, so I won't count it)

2) Request Batching

This approach is popularised by Facebooks Dataloader library
[https://github.com/facebook/dataloader](https://github.com/facebook/dataloader)
Instead of directly querying the database in the resolver, you return a
specification of what data you are interested in. When all resolvers on the
same level in the query has returned this specification, the Dataloader
library figures out how to batch queries together as much as possible

3) Big Join

You can inspect the GraphQL query in the top level resolver and basically
perform one giant join up front. You will then pass the entire value down your
resolve hierarchy, and all they have to do is pick out the correct data from
the complete result set. Take a look at join-monster if you are interested in
this approach.

The Graphcool hosted backend is serving millions of requests an hour using the
Dataloader approach, and we have found this to be more flexible and more
performant at scale than generating a big complex join up front.

For most queries we see single digit millisecond response time for a batched
query, and the time complexity scales linearly with the depth of the query,
which is not the case for joins.

~~~
zackify
2) is easy, but leads to two queries no matter what, because you have to do a
whereIn

3) here's the code:

const EagerQL = (info, allowed) => { let fields =
info.operation.selectionSet.selections[0].selectionSet.selections; return
fields .map(field => field.name.value) .filter(field =>
allowed.includes(field)); };

// in a resolver user(_, args, context, info) { let eagers = EagerQL(info);
console.log(eagers); // ['posts'] }

This will give you fields that were queried for so you can do a big join. Hope
this helps someone :P

~~~
joesb
trying to access fields like
`info.operation.selectionSet.selections[0].selectionSet.selections` always
feel wrong to me. I wish graphql library part comes with some utility function
for these.

~~~
zackify
Completely agree.... I don't understand why there isn't a more standard way of
accessing the fields queried for so that you can do joins.

------
pier25
The image is pretty misleading. It looks as if GraphQL server connects you to
REST and SQL.

In fact you simply have functions called _resolvers_ where you write your
logic to get data from wherever you want. SQL, NoSQL, API, filesystem, etc.

~~~
joesb
I think the idea is that you shouldn't want to have GraphQL server code
containing business logic code in it.

GraphQL should just be proxy layer between actual client and the actual,
multiple, APIs.

~~~
pier25
But then why connect it to SQL and Redis?

------
aarohmankad
Is this a direct replacement for graphql-server-express?

I've been using it while following along the backend JS tutorial at
howtographql.com and was wondering if it's now outdated and what the migration
would look like.

~~~
djmashko2
It's exactly the same thing but renamed - we're going to make both names work
for a few weeks and then deprecate the graphql-server name after all the
resources are updated. It's exactly the same, just change your import to
"apollo-server-express"

~~~
aarohmankad
Awesome! I would suggest updating your documentation, as there are some places
where the graphql-* variant is mentioned.

~~~
djmashko2
Just did it, thanks so much!

