92 comments

[ 2.4 ms ] story [ 164 ms ] thread
Uh, main feature of graphql is a graph cache and graph model itself. It has nothing to do with HTTP2.
That's basically what the article says though. The connection to HTTP2 is that they both try and minimize the amount of requests made to a server. The author is just pointing out that GraphQL has more to offer than reduced requests.
Then it was a fairly useless question to ask to begin with.
Making a request to the server is completely different than opening a new connection. HTTP/2 lets you use an already opened connection, if applicable. Thus it is able to bypass making a handshake/etc. for every request made as well. Making a request however will still have to traverse the network irregardless. GraphQL gives you a query language to tell the server what you want in a single request. So if it is your first request to server, and a new connection needs to be opened, HTTP/2 is irrelevant. Basically, HTTP/2 and GraphQL have NOTHING to do with each other.
That's not the point I was trying to make. I agree they are essentially unrelated. But they do both try to reduce requests made.

From the article:

> Not only that, but HTTP/2 has a new concept called Server Push. Without going into too much detail, server push allows servers to preemptively send responses before the client requests them.

GraphQL has nothing to do with graphs and caching GraphQL is an exercise in masochism. And it's not even a query language in the sense of SQL. It's just about the worst named tech we currently use, IMO.
Yes, calling it a "QL" was a huge, huge mistake, judging by the amount of comments on HN and elsewhere asking questions that are clearly influenced by an understanding of SQL but are basically non-sequiturs in the world of GraphQL (e.g. "How do you do AND joins with GraphQL?").

I admit, I didn't read the article, but even it seems like (mostly) a non-sequitur to me based on the title. Minimizing network requests is one teeny part of why I like GraphQL, and do say "we don't need it because HTTP2" is completely absurd.

It would be irrelevant only if the sole reason to use GraphQL is to minimize network hops and bandwidth. I'd argue that, if that's the only positive you see in GraphQL, then you would be just as well off writing custom API endpoints for each view of your application.

I prefer interacting with GraphQL over RESTful interfaces. From my experience, it's less prone running into bugs inherent to client-side joins of API responses, easier to evolve iteratively, and generally more pleasant to work with thanks to its introspectable declarative schema and flexible query language.

It's refreshing that the author acknowledges the nuances around tradeoffs of using, and not using, GraphQL.

Having used REST (with swagger/openAPI), gRPC and now graphQL, the most painful thing has been the tribal militance from supporters of each, defending their own vested interest.

It's almost like different tools are useful for different things.

> tribal militance from supporters of each, defending their own vested interest.

This is something I really wish I understood before going down the road of graphql. I think it's a great technology, but the developers supporting it are making it nearly impossible for a legacy codebase to ever adopt.

Ex: so many JS codebases use redux. Apollo is a popular graphql framework that supported redux integration for some time, then suddenly ripped it out. They cited performance concerns, but I looked through the code myself and it would seem they just have a bias against redux. This issue thread makes that especially evident: https://github.com/apollographql/apollo-client/issues/2273

We were very lucky to have found that before breaking ground on the work.

Which is ironic because Apollo 2.0's caching mechanisms have some very serious performance issues themselves, and they take almost all the power away from the user (unless you want to implement your own cache from scratch).
I believe one of the main selling points of the upcoming 3.0 version is indeed to make the cache more usable with manual evictions, etc.
From the linked article:

> With all of those caveats noted, HTTP/2 should put to rest any notion of the need to minimise the number of requests for APIs; the protocol makes them cheap enough to not practically matter. Go ahead and design a highly granular HTTP API to meet the needs of your clients

This seems highly misleading and missing the point. Sure, you can send a lot of requests in parallel with http/2. But you still incur significant latency if these multiple requests are dependent on one another and serialized. For instance, suppose you have 2 granular APIs that:

- Returns all friends for the specific user

- Returns the name, age and hometown for a specific user

Suppose your client wants to get all of a user's friends whose hometown is NYC. Even with http/2, it has to use the first API, wait for the response containing a list of userIDs, then use the second API to get all of their hometowns.

Whereas with GraphQL, it facilitates building a single API call that says "give me all friends for a specific user, along with each friend's hometown". Now, there is only one round-trip latency cost. Not two. Even with the overhead improvements mentioned, the cost of two back-to-back round-trips would be much higher. It is very odd that this isn't mentioned in the article or any of the other articles they reference.

Why wouldn’t you return more data for the REST API instead of making dependent requests?
Because then 2 months later a dev refactors the front end to only require one of the fields, and suddenly you have the gorilla holding a banana and the whole jungle when all you asked for was a banana.
Yeah, it'd sure be nice if there was some way for the client to specify what data it wants.
I do that for my backends. On the HTTP request, the client sends a `?fields=encodeURIComponent(<JSON>)` query parameter to the server. If `fields` is present, then the API sends back the pruned version of the REST API. If `fields` is not present, then all the fields are sent back. Alternatively, you can prune the fields to a subset by default. The <JSON> looks like `{ foo=true, bar={baz=true}, bap=true} ` to imply the endpoint should send down field `foo`, nested object `bar` with only its field `baz` and the entire default nested object `bap`. I achieve this in Django Rest Framework by using meta-classes.
The people who write the API would need to know you want that data and implement the change, or write a new endpoint that returns the user details and the friends details in one request. With GraphQL the API wouldn't need to change; you'd just need to write the query on the frontend and it'd work.

For most web apps the overhead of adding a new endpoint is small so the benefit of GraphQL is also small, but if you're Facebook then GraphQL makes a huge amount of sense.

GraphQL is not a substitute for communication. You should be communicating your query patterns because all fields are not equal.
Because loading all the friends for a user needs to be done in five different places with slightly different data in each one, and loading the data for each request takes 500ms combined but only 150ms separately, plus there are specific questions about each friend like "is this friend in event X?" that only make sense if you know what X is, and when you add a parameter like event=X you notice that there's already an event parameter that does something else and all these different cases are becoming messy, your backend logic had started to reflect the frontend, and you wish you had some kind of way to query your graph of users to retrieve exactly the fields and embedded relationships you need.
see, this is where things like apollo client shine.

one part of the page makes a request and the rest of the page gets to use the data because now it’s in the local object cache.

I get what this article is saying but there is a lot more to graphQL than reducing network RT. It’s about replacing statically defined REST API responses.

As a prior commenter wrote, it’s making the backend more flexible when the front end devs change their mind.

GraphQL can support arbitrary numbers of fields and arbitrary nesting of relationships. You can do this:

    {
      hero {
        name
        friends {
          name 
            friends {
              name
            }
        }
      }
    }
But some clients might only need this:

    {
      hero {
        name
      }
    }
This is a small example, but it's pretty clear that "always including all fields and nested relationships in every REST API response" is not a viable solution.

(GraphQL examples based on the schema used in the official documentation: https://graphql.org/learn/queries/)

At my previous job we had a method that became known as a "superset". It would fetch a record and all data related to that, and then a lot of other data related to that. It would return tens of MB of XML every time. It was huge, but so many services came to depend on it because it always had that piece of data someone needed.

All the data you needed was there, but every request caused a lot of memory usage and lots of database queries. GraphQL allows you to just ask for the fields you need without necessarily incurring the cost of returning anything else.

I think the Fields: header in the library is supposed to be used for that, it would look something like

   Fields: /users/*/hometown
in the same request.

It feels like it’s solving all the wrong problems to me - who actually wants to put varnish in between GraphQL client and server? Caching can be done more efficiently at either end. And this doesn’t provide a replacement for a query language, just moves some of the optimizations to the transport (http2) layer.

Now I’m wondering why Apollo doesn’t use http2 push to batch requests, instead of merging queries. Or does it?

Now all they need to do is allow the fields header to represent arbitrary graph structures and they will have reinvented GraphQL poorly.
This also ignores things like Hasura which does global optimization by converted GraphQL into a single SQL query.
> Whereas with GraphQL, it facilitates building a single API call that says "give me all friends for a specific user, along with each friend's hometown".

Better yet, submit a request asking for all friends whose hometown is NYC (or whose hometown is the same as one of the user's previous hometowns, or...). That way only a subset of the data needs transmitting.

It's not really a valid argument, because if you only have two APIs and you can't create more, you can't switch to a GraphQL implementation in less time than you could add an appropriate endpoint.

  GET users/<id>/friends
       ?fields=friend.*
       &where=hometown:'NYC'
       &aggregate=distinct
http2 has push, so you can make a single request (for the friends of a user) and then just push all the users in that response before the client requests it. this all happens over a single connection and leverages all the http infrastructure and experience you already have
Even directly accessing a database on localhost, your code will be slow if you send "select id from user where user.friend = ?" and then 1000 times "select town from address where user_id = ?" rather than one query with a join.
> Suppose your client wants to get all of a user's friends whose hometown is NYC. Even with http/2, it has to use the first API, wait for the response containing a list of userIDs, then use the second API to get all of their hometowns.

Not only that, but the resulting set will have inconsistencies if the database changes between the two requests. It's very unusual for HTTP applications to maintain transactional consistency over multiple requests.

This can be a security issue among other things, and even when it isn't, it can result in the display of glitchy data, whose inconsistency persists in the client which fetched them.

For example, you get all of the user's friends' userIDs. Then the DB is changed to remove one of the friends (by that friend). Then that friend changes their hometown to a new place, that they don't want the original user to know, and expects the original user can't see.

Then you do the second API call to get the hometowns of the userIDs. The result contains the new place that you should not have been able to access, and maybe it's shown on a screen for an unbounded time after that, or printed in a report.

Similar issues occur when fetching data to sum into totals and finding it doesn't match an expected total, or expecting some logical constraint to hold for every item in the result because it's implied by the original query.

(Live-streamed query updates turn these into momentary glitches, which is still wrong but at least those disappear from view soon after.)

> Then you do the second API call to get the hometowns of the userIDs. The result contains the new place that you should not have been able to access

This is an issue with access control, not HTTP requests. The second HTTP request shouldn't return information you don't have access to.

Not really, that's just an artifact of the example, which I constructed to emphasise that consistency errors can be serious.

But I agree that if access control were used (and pushed down to the database, rather than implemented on the client side), it would prevent that particular example from returning the disallowed data.

Even with access control the problem is still there. In the example but with database-level access control added as you suggest, the client gets an access error instead of a consistent resultset. Or missing data instead of a consistent resultset. In either case, the client needs extra code to handle the inconsistency caused by the sequence of dependent HTTP requests, or it will render an invalid screen. In some cases, maybe throw errors trying to render it because the data is in an "impossible" state that wasn't allowed by the database logic.

For example, a person without an address is shown, even though the database never contains a person without an address. Or nothing is shown, because of the access error, unless the client has "retry on access error" logic.

Try to imagine how unprofessional that would look if it was, say, a bank statement line without an amount.

These inconsistent data hazards can get complicated easily, as they arise from all sorts of weird corner cases that rarely arise and are hard to enumerate. Defensive programming is needed to handle them, and even then it can be hard to ensure every case is handled well. They are also hard to test.

This is an interesting article!

A few weeks ago I found an interesting open-source project that tries to combine the best of GraphQL and REST, though it's more tilted towards REST.

https://www.graphiti.dev/guides/

We haven't switched our API over just yet, but are planning to do so.

Graphiti is based on the JSONAPI standard. While Graphiti is an awesome library (the author is one of the most supportive devs I’ve experienced with OSS, rivaling most paid support I’ve experienced), JSONAPI has existed longer than GraphQL, and has virtually no relationship with GraphQL or how it functions.
Title sounds so wrong that I'm unable to click on it.
Totally. doesn't make sense at all. Sounds like "Are burgers still relevant in coffee-table world"? HUH? What the f did the author smoke before writing that?
I'm a reluctant user of GraphQL. I can't specify any deep technical reasons, I just prefer a lot more control over interfaces - particularly where I'm in control of both the client and server.

But. I use GraphQL. GraphQL is a whole toolchain around client-server interactions. (IMHO) It's a pain to get started using is, but then the benefits of tooling start to compound.

HTTP2 won't replace GraphQL. Perhaps a set of libraries that use HTTP2 effectively. Even then I'd be surprised if it was a huge departure from GraphQL fundamentals - but you never know.

In a discourse where GraphQL is just an additional layer over "REST" services to make sense in terms of network roundtrip, and similarly HTTP/2 server push is used to bundle multiple "REST" results, it's worth noting that there's always the option to use more unopinionated approaches to request/response payloads such as RPC- or SOAP-like protocols merely seeking to model payload syntax without implied semantics and restriction to "GET"/"PUT" primitives. Locking your response semantics to network interactions such as in "REST" never made sense from an engineering PoV IMHO.
Can someone please explain what GraphQL actually is? I've looked at it multiple times but never got super deep... my limited understanding is that all it is is basically defining a schema so that when issuing API requests, the client itself can make it's own "query request", rather than talking to an app backend which has SQL queries programmed/written in an ORM or some database wrapper.

I feel like I'm missing something, as that seems incredibly limited, especially with things like performance (where queries need to be tuned and refined and custom written. Just a simple SELECT * FROM X INNER JOIN Y and horrible N+1 isn't good enough)

Can someone please explain what is GraphQL once and for all?

Build the data request you want at the client rather than the server
I went to a talk where it labeled it as halfway between a dsl and sql. I haven't used it in about a year.

``` user { id, first_name } ```

would on the back end map to a function that runs something like.

``` select id, first_name from users ```

So the fields are dynamic in a way. Allowing you to select only the data you want. You can also nest data calls, like joins.

``` user { id, first_name, user_profile { bio, recent_comments } } ```

This would execute the above. Then take that user object into a query context. That query context allows you grab any elements from the parent returned object. I.E. the user id.

That would then execute the nested query like

``` select bio, recent_comments from user_profile where id = $user.id ```

So instead of rest end points. You are building a number of functions that return an object. You can then define relations that operate off of those returned objects. You can also restrict queries in production. So only white listed / approved queries are run.

A schema is a list of all these objects that may be returned and their relation also including type. Instead of a reverse proxy like nginx. There is schema stitching. Which combines all the schemas into one big schema. When querying it will proxy the respective calls to the respective back end services.

I did a talk on GraphQL a bit ago, so it may be out dated.

https://blog.animus.design/kotlin-backend-presentation/

Corresponding repo

https://gitlab.com/AnimusDesign/KotlinIMDBDemo/blob/master/a...

I've not used Graphql in production. When I was researching it's ecosystem anything outside of JS leaved a bit to be desired. That being said. It's a solution to a problem.

Openapi can generate clients. But if you need to make six calls. It's not performance or transit time. It's cleaning up the errors on that. Waiting for one to respond then another. From that vantage point I see the benefit. One query get what you need. If anything fails along the way it stops. It shifts the error checking pattern to the server.

Additionally in react and even mobile. There are redux or state machine stores that operate strictly off of graph ql. You've now centralized data retrieval, and state management of the app. That's a pretty big win.

https://www.apollographql.com/docs/react/data/local-state/

All of this is very beneficial to the front end / mobile. Easing data retrieval, being more expressive and type safe. But it's the front end driving how data is presented and stored to an extent. By using graphql to get the best support you should be running on node.

Awesome explanation, thank you
GraphQL allows you to not only fetch a single piece of data, but allows you to also fetch related data, ie traverse the relational graph of data. So if you have friends, and sometimes want to fetch your friend's latest posts/pictures, you can do so as you like with one single query. In REST, you would first get all your friends, then for each of these friends get all the posts/pictures as individual queries.

In short: it allows you to query a database much more naturally in one go, rather than having to fetch data, and depending on that data then fetch more data. On top of that, it's typed, relatively easy to learn and well documented. I'd highly recommend it, even if it's a tad more complicated than plain REST.

I guess I already do this with "REST" (although I get it's not really called that much if I don't strictly follow 1 resource per request). But I very often just make endpoints that have custom SQL written that touches many tables anyway.
That seems to be how most people do it in the wild if they don't have any reason to try to stick with a pure REST/HATEOAS API. Frequently when people say they do "REST" that can mean as little as "we use different HTTP verbs for the same endpoint to distinguish between calls rather than putting those verbs in URLs" (e.g. POST to a collection rather than to a route "/new", DELETE to a resource rather than POST to a route "/delete").

GraphQL was developed at Facebook and Facebook has a massive backend API used by many different teams for many different purposes. In this scenario the trade-offs were apparently worth it because purpose-built endpoints for each feature were likely not scalable and would have required deep knowledge of the full stack to implement.

In teams of 1-10 people with an API that serves a single app controlled by the same team, I'm not convinced GraphQL adds much apart from adding a layer of complexity to the architecture.

Makes total sense, Thank you
(comment deleted)
It's like a dumbed-down version of SQL for clients to query the server. It's not totally arbitrary, it kind of let's you tie together micro-requests. You backebd might be using an ORM. It might be pulling data from 10 different places and exposing them in a single api. Optimisation can be an issue.
Basically GraphQL is an API contract between a client and a server. The contract defines what data, through types and fields, is available.

The server must fulfil this contract by providing methods (called resolvers) for each field.

The client must fulfil this contract by only asking for available fields.

The query language is built to support highly nested data.

Now, the N+1 problem you are talking about is not a GraphQL problem, but an implementation problem. Depending on how you write your server methods you can get it down to very few db calls (some use a thing called dataloader. Other tools are hasura or postgraphile)

(comment deleted)
Yes - (and totally reasonable question, btw - it's remarkable how hard it is for the folks behind it to just plainly state what it is vs. coating it in buzzwords).

BTW - I may be wrong / misunderstanding something here as I'm only in the research phase, but here's what I got:

GraphQL is an alternative to REST as a way for clients to query servers for information. In a REST query, you hit an endpoint and add optional query params. But you get back results based purely on what the server has been singularly designed to give back. For example, if I query:

GET /users/1

I'll get back a user object that the server has been programmed to return. It's of course possible to customize this with query params, and do something like:

GET /users/1?only_include=first_name,last_name

But that's the exception to most RESTful APIs, not the norm.

In a GraphQL query, the client specifies _exactly_ which fields it wants back, and that's baked into the design. So the client would submit a query like this:

{ user(id: "1") { first_name last_name } }

And the server would return exactly the object the client asked for.

There's no magic here -- that's the part that many people have trouble explaining. When you write your GraphQL server, you still need to write the actual queries (<--- this is the key!). But structurally, you write more generic queries -- you'd say "when a client requests a user, run this SQL", "when a client requests first_name on a user, run this SQL", etc. etc.

That way on the server, you write isolated query resolvers (called, amazingly enough, resolvers), each of which get run when a query comes in.

This is as opposed to a RESTful approach, where you'd do a more traditional single SQL query for the /users/:id endpoint (SELECT * FROM USERS WHERE ID = ... )

Hope that makes sense (and is accurate!)

Super awesome answer, thank you! Im glad you validated what I thought about how insane it is to read about it without drowning in buzzwords so much that I stop reading. Thanks again
Your understanding matches my understanding, but you missed the point which was the "ah ha!" moment for me. Which is that the front end developer can design their own endpoints without bothering the back end developer.

When a front end developer wants to request a specific shape of data (e.g. All the people with age between x and y who are within a distance of z of the logged in user and just get their name and list of interests) then with REST they have to either compose that data from the available endpoints or bother a back end developer for a new endpoint.

With GraphQL the front end developer can compose the query themselves without knowledge of any back end technology beyond the GraphQL schema.

E.g. they'd write something like the following, using either a schema reference, or introspection-powered autocomplete UI to find out which fields are valid.

    query nearbyCandidates {
        allUsers(filters{
            isTheLoggedInUser:false,
            ageBetween:{start:x, end:y},
            closerThan:{distance: z, from: [LoggedInUserPosition]},
        }){
            interests:{
                interestName:name,
                description,
            }
            candidateName:name,
        }
    }
This actual story is a bit of a fairy tale because you'd still need the two developers to interact if the required fields or filters did not exist.

Finally the general theme of the comments here, that there's nothing stopping you using both, is accurate.

Unless you are using something like Hasura which in many cases negates the need of a backend developer. Front end developers can have almost total autonomy.
GraphQL seems to be mostly touted as "You can do richer queries!". which is definitely true, but not the key factor of what makes it awesome in my experience.

Much more important to me is how it allows the backend and frontend to work closer together. I can simply send the frontend developers my schema and then they know exactly what each endpoint returns, down to the exact type of the returned keys. There's no more back and forth on what the data for a new endpoint is supposed to look like. Either the backend devs take lead and hand a schema to the frontend devs, or the frontend devs take the lead and hand a schema to the backend devs.

Other than that there's quite a lot of really cool tooling. On the backend (python/django) I'm no longer needing to write long-winded serializers for each specific kind of view. I can simply make a query object that returns the right database query. On the frontend (typescript/react) they no longer need to write types for each API view, they can simply hand the schema to a code generator and get a file out declaring all the types the API deals with.

GraphiQL is awesome for both frontend and backend devs, At the very least it's a tidy small editor for queries. It allows you to run queries as you're developing or testing views. The documentation pane shows all the return types and expected arguments and types even if you don't put any effort into documenting anything. If you do put effort into documenting it becomes a powerful API documentation that's be easy to keep up-to date.

We're still in the early days of using graphQL but what I've seen so far certainly is worth the growing pains we're going through. The only real nitpick I have is the poor documentation of graphene-python, quite a lot of crucial use cases have you running around stack overflow and the source code to find answers. The case that gave us the most trouble so far (backend and frontend) is what to do with errors. We've gone the route of having views returning a union of the result and a global error type, which seems to be working nicely so far.

Of course the richer queries are nice too, but for us they seem to be mostly limited to making queries return less info when possible. e.g. when querying users you don't always need to return the entire user, which graphQL supports nicely, allowing you to elude profile photos or other expensive-to-calculate-columns whenever needed.

This seems like a false dichotomy. In my eyes the point of GraphQL is the query model.

HTTP2 is just a transport, you still need to put something on it, like gRPC.

Seems natural that GraphQL will evolve to use it, and benefit from the technical improvements.

I really like the server push model, but not sure how to square it with GraphQL way of doing things.

> In my eyes the point of GraphQL is the query model.

Yeah me too, I would compare restful to GraphQL and HTTP2 to HTTP1. It is also annoying that the author hardly mentions restful APIs or it's shortcomings.

We've been developing a GraphQL api for the past few years and I really really really like using GraphQL. From a developer experience perspective, it's so much easier to work with than traditional REST based API's. I could add more but I'm pressed for time and I simply wanted to leave my +1 comment for GraphQL. Happy to answer follow up questions (if any).
I worked with GraphQL a bit over a year and half ago on a project. I was the front end consumer, working with backend microservices via graphQL.

I wasn't sold on the GraphQL hype then, and I'm still not, but this article seems to miss the point. [Edit: I mean, it agrees, but it does so poorly]

A lot of people TALK about the lack of multiple back-and-forth, and about not wasting unnecessary data, but honestly, that wasn't a big deal. I expect there are some situations where that comes into play, but for most people the appeal of GraphQL lies elsewhere. If HTTP/2 means that's less of a big deal, I don't expect much change.

The legit upside to GraphQL was that backend could change rapidly without breaking compatibility for existing consumers. Some changes could be fixed purely frontend by changing the query, but if we needed new data that wasn't provided (or a variation on data that was provided) the backend could add that AND NOT IMPACT EXISTING CONSUMERS. That's not the only benefit (and remember, I remain a skeptic) but that was by far the biggest and was definitely real.

Even if the claims of HTTP/2 rendering the call overhead are correct (see other comments to doubt that), that has no impact on this value of GraphQL.

> I wasn't sold on the GraphQL hype then, and I'm still not,

Why not?

Foremost, I'm not comfortable with abandoning the meaning of HTTP methods. Changing everything to POST means pushing all sorts of caching decisions to the start-and-end points and bypassing decades of work done on improving GET caching for intermediate layers. (Caveat: this is where people start talking about how GraphQL doesn't _require_ POST. I fully allow I don't know enough to be sure, but on the face it seems problematic).

Secondly, it may just be something solved as the tech becomes more mature and practiced, but there are numerous smaller issues such as versioning (the ability to change rapidly without breaking backward compatibility is separate from when you DO want to break that compatibility) and tooling. These are hardly solved issues with, say REST, but they are "more solved". Most places have some level of versioning, and requests are trivial to read with existing tooling.

When doing an involved front end app (I was in ag tech working on app that was tying data models with farm field overlay maps and setting values by geographic region - which sounds way more impressive than it really is) I found that GraphQL seemed great for straightforward CRUD apps, where the results of a query and the display of the page mapped closely, but the value add on the front end was pretty minimal for more complex applications. Lots of tooling (Apollo at the time, and I hear "Relay" being discussed today) performs magic to make this all effortless.

"magic" is great when it works - we adopt it and stop considering it magic. The other times it is usually a flash in the pan that spawns lots of regrets. I'd be an idiot to claim I knew which side of magic this falls on, but my experience is currently saying to avoid anything too involved. A GraphQL API? Sure, it's not my first pick but I'll use it. A framework that magically hides all the complexity on the front end? I'm willing to bet I'll run afoul of some hidden boundary.

If I'm at a company that starts talking GraphQL I'd ask about the solutions for caching and versioning. If they have answers, I'll keep listening. If they wave it off as something to worry about later, I'd expect headaches.

A long, rambling, and subjective answer, but that's my answer.

AFAICT, the point of GraphQL to get an API that corresponds to your React state tree, so that there's much less mental overhead from client developers who don't want to deal with multiple shifting data representations.

Batching almost seems like a nice-to-have.

I guess in theory we could take a gql query like:

  query {
    user {
      first_name
      last_name
    }
    settings {
      debug
      paid
    }
  }
could be translated into:

GET /user/first_name GET /user/last_name GET /settings/debug GET /settings/paid

And you could represent any gql query as a multiplexed http2 call. And you could then have the server use a persistent user scoped dataloader (or some other shared cache) to resolve all that data and respond to each of those queries.

That's roughly an isomorphism between graphql and http2.

I suppose so. As someone who hasn't used GraphQL, isn't most of the appeal in GraphQL attributable to the fact that you don't have to manually write all these rest endpoints? In that way, I don't see GraphQL as irrelevant in light of HTTP2; the goal of the former being to take the overhead of writing endpoints off the backend team.
With one notable difference that the multiple GET requests can be (much) more easily cached than the GraphQL example.
In reality, that would be GET /user GET settings; the cost for the unneeded associated fields at that point of time is typically not significant for many backends as they stored in aggregate and text based responses compress well.

If the data is not particular dynamic then you can cache the entire representation deriving a future benefit.

Graph base queries tend to lend themselves to adhoc query patterns and I would be concerned about unpredictable patterns of loading. If the backend store is distributed then graph QL looks more attractive to me. If the datastore stores related attributes in aggregate there seems to be little benefit since different parts of an adhoc graph would different levels of 'cachability'.

I have found an application for GraphQL in storing soft-defined triggers or other criteria on data.

1. Depending your database technologies, queries are still going to be more efficient with batched operations.

2. HTTP/2 doesn't make latency/speed of light zero.

3. Outside of performance, GraphQL is a type-safe, error-minimal way to perform joins and searches.

What about HTTP/3 for your second point?
Same.

Query, Answer, Query, Answer

has twice the latency of

Query, Answer

No it doesn't. It depends on how long the query<->answer time is, and if it's the same. A complex GraphQL query may well take longer than 2 simple REST requests
It would seem to me as a casual observer that GraphQL is more an alternative to SQL than it is to HTTP2. No?
Yeah. The advantage of GraphQL is that you can bring the exact data you need with a single API call instead of querying against multiple endpoints to assemble whatever data you need.

That's completely independent of the protocol that you're using. I understand that there's a performance consideration when you have to make fewer calls and how HTTP2 basically can help with that. But I honestly have never thought about GraphQL as something that would improve performance.

For me, the advantage of GraphQL is not that it reduces network roundtrips but the fact that you can get the data you need in the exact structure you need it.

Having built a lot of react apps with and without flux/redux, I would say the best part of GraphQL is the simplification of SPAs. Building up the query with fragments and colocating data fetching with the component that need it, is a huge win. If you have lots of micro services or even a few SOA apps, GraphQL is “developer ergonomic” win.

Majority of the latency/bandwidth wins can be achieved with a well architected jsonapi. This should not be your only reason for choosing GraphQL.

The biggest problem GraphQL solves is not a technical one. GraphQL is an enforceable contract between clients and servers that encourages APIs to be designed in a way that best serves the client, and in doing so, the end-user. Clients used to spend an inordinate amount of time and thought in simply getting the correct data from the server. So much so that entire FE frameworks and libraries evolved to essentially pull all the server’s data, organize it into UI-friendly chunks, and then (and only finally then) create an experience the user would find valuable. It was a small miracle if any time or energy was left to make the user experience enjoyable too.

A litmus test for a well designed GraphQL API is: could you tell what the client looks like and what the client does simply by looking at the schema? GraphQL forced everyone to think about the end-user experience, and to be on the same page. Literally. And that is it’s greatest strength.

Ignorant here: why not just use a subset of SQL?

It needs a filter and it definitely needs to be applied to a limited, custom view of the actual underlying data, but… that’s what you have to do anyway with a REST or GraphQL API.

By the time you’re done making your REST/GraphQL API “really flexible” couldn’t you just build an SQL filter?

All the APIs I used to so far are so limited. For example there’s no easy way to query multiple posts at once on GitHub’s GQL while that could have be an extremely simple `SELECT title FROM issues WHERE id IN (13,57)`

It's bad to write SQL queries on the client side :-)
Exactly. That's why we needed a new tool that does exactly the same thing, but allows us to say we're doing something different. </s>

I have always had the impression that graphql was built for a problem Facebook has, but that most of the rest of us don't (numerous complex backend (some non-SQL) data sources and highly independent frontend teams moving very quickly).

As I work in an environment where there are no frontend vs backend developers, and we have a single SQL database, graphql is a neat tool which solves some problems I will probably never have.

Well I use graphql to get data stored in Redis, ElasticSearch or is just calculated on the fly. It’s just an api endpoint.
Is it?

Or is it just bad to pass unsanitized SQL queries? Because that’s the only issue I think. GraphQL seems effectively an input data sanitizer.

Or you could use a zero coding backend solution on top of a database like Hasura or PostGraphile.
Just like there’s Hasura there could be a zero-coding tool that does the same for SQL.

I’m not arguing that the average developer should write an SQL query sanitizer but just that what companies are investing into GQL could be invested into something more flexible.

Sometimes we discard tools and ideas because at some point in the past they were poor or bad practice. See PHP and IE.

GraphQL has a very specific cross-functional advantage: it provides a spec for data access, to cut down novel design (of APIs) by backend and frontend.

If Backend have few data entities, or the requirements are extremely clear, your team is not likely to get the full spectrum of benefits.

If you have a large number of existing Backend data entities, or expect a large number to be created - GraphQL is a very handy spec. But if the Frontend/Product are EXPLORING how use the data, and unsure exactly how to best utilize the data types, OR they are supporting many permutations of APIs, GraphQL is a game changer. Write a python decorator to generate resolvers...

- and BOOM, Backend and Frontend will never have to negotiate over a rigid & novel API contract again.

The other stuff, like introspective documentation, sophisticated Frontend state management, and so on are great conveniences, but are not the point.

As far as HTTP2 and Frontend goes, I'm excited as it solves a fundamental networking problem. And theoretically saves us from having to bundle. But this is not what I personally consider a big Frontend problem.

In most large webapps with network-connected components, you don't want each component to make a discrete network call and pump its data straight into the component. Often you will want to use the response and update a global state, to ensure nothing is out of date. This encourages you to colocate your network logic, with some facilities for this. The GraphQL ecosystem ticks this box. Additionally network requests are a complicated flow, due to APIs having different semantics, needing to shunt value objects through promise/callback chains and the need to covering various edge cases. This encourages codification of network logic, which again, GraphQL does a great job of.

This is of course quite complicated stuff, and if you don't need the Frontend magic - you can just put your GraphQL query on a fetch, and use it like a REST endpoint.

And of course - if you don't really need the spec, I'd say think very hard before adding GraphQL.

That said, big fan of HTTP2 (although last I looked, the perf envelope created by plotting no. of connections against speed, the shape told me "don't rely on this yet").

One problem I see with Graphql, in general, that it seems like it amplifies a problem which is something all OXMs inadvertently do. And it is the problem of managing business logic. And from what I can see is that graphql now pushes this to the client and erodes the server side’s encapsulation of business logic. Now you have the problem of having business logic everywhere? Isn’t this something we have learned throughout the years is a bad thing?
but facebook...

(your description appears accurate, and in-fact, that is precisely what this enables, and it's symptomatic of team (human) interactions rather than technological drivers.)

Apollo is a product of the Meteor Developer Group, if I'm not mistaken. FWIW.
GraphQL is barely relevant today with the older HTTP standard. There is a very limited use case for GraphQL, and you most likely don't need it. If you are new to GraphQL I would recommended simply trying to use it to delete an item by Id. While this is a trivial task if you were using the MongoDB with Node/Express.. just and the GraphQL Layers.. and see all the extra code you need..