We currently have a massive number of view models, which are responsible for transforming models or collections of models into payloads for consumption by various client endpoints. Each payload method takes a whole suite of options to allow us to select this or that subset of fields, or to eager load this or that join. In the cases where we have heavily disparate payloads, we've ended up with parallel several implementations of "here's how to generate a JSON object". It's a giant mess - it's worked, but it's a mess.
GQL completely eliminates all of that. Each payload specific to each view is now specifically enumerated via a GQL query. We basically took all our individual field helpers out of the view models and implemented our GQL field resolutions with them - the actual translation work was minimal.
The end result is that a) we have massively less code developing payloads and b) we aren't overdelivering massive amounts of JSON to client endpoints because implementation X happened to be a superset of the data that we wanted. It also solves the problem of "slow bloat" - you implement a #to_json for one view, use it, and later another view uses this, but needs to add an extra field. Now both views retrieve that extra field. Repeat this process over 5 years and multiple consuming views and you have gigantic payloads which are mostly wasted in any individual context.
We even still support our legacy REST API with this system - the app can act as a GQL client, making a query and then emitting the response as JSON. Our REST API is now just one specific, brittle subset of our GQL functionality.
As soon as you find yourself wanting to customize your data serialization per view/endpoint, GQL becomes extremely useful.
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 by Graphcool and all the cool stuff Sashko is talking about in this presentation.
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.
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.
Because you can't possibly now what your API consumers use on their side.
That's the best part - with GraphQL you _do_ know, since people have to ask for every single field they want.
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
I think that's an immensely useful thing to do - that's why I've been doing it for years by using Thrift instead of REST :). Is there still a value proposition for GraphQL if I'm already using strongly typed interfaces?
Here's how I think of it. (Others can correct or elaborate my understanding.)
Let's say you have 1 REST endpoint such as "xyz.com/customerlist" to return a JSON response and behind the implementation is a SQL "SELECT ∗ FROM T" and you get back a 100k response with all rows and all columns. You really only wanted customer's name and zipcode and you only wanted it for region of New York. (Unfortunately, "SELECT ∗" returned 30 columns which is 28 more than you need. The REST endpoint also didn't have a SQL WHERE clause which returned all 1000 rows where you only needed 20 rows.) You actually only needed 10k out of that 100k so you threw away 90k of data. Downloading data you throw away is especially wasteful with smartphones on slow mobile connections.
To address the finer grained slices of data, you either create more REST endpoints ("xyz.com/customerlist_name_zipcode") or add query parameters at the end of that 1 REST endpoint. It's doable but multiple endpoints will lead to a combinatorial explosion and the maintenance of them is not ideal for fast iteration.
With GraphQL, the client can request the "shape" of the data without having a pre-defined static REST endpoint that matches that shape. You can thin-slice the data without wasted bytes. The clients can get unforseen shapes of data that the developers of REST endpoints didn't envision.
I actually think the GraphQL landing page explains the rationale and motivation very clearly: http://graphql.org/
Is that different than GraphQL?
Instead use GraphQL which is a thin layer, and hide all the business logic behind it. Way more manageable.
On the backend you'd probably need sql query analyser that would figure out which tables and rows query touches to determine if currently logged in user should be able to see this data.
So on frontend you need a language in which components can specify their needs (why not graphql?). Next step is asking youself why flatten those to sql before sending them to server only to have it parsed again by the server. It's easier to pass them as grqphql and let server decide if it should respond and draw from data source (or possibly multilple data sources, for example solr and database).
Congrats, you invented graphql. Too bad nobody came up with that 15 years ago, this could save a lot of people a lot of trouble.
I think recent "@rest" addition from Apollo ( https://dev-blog.apollodata.com/apollo-client-2-0-5c8d0affce... ) shows they can easily live together - backend uses REST and frontend can rely on GraphQL.
http://samnewman.io/patterns/architectural/bff/
We have data repositories living behind very simple REST controllers, an endpoint probably doesn't take that much longer to write than a GraphQL query.
I think there are 2 differences:
1. It's very very easy to write a GraphQL query, since GraphQL comes with auto-completing tools to do so. Even non-technical staff at our company often use it to get information about customers, etc. 2. The query is written inside the client codebase, which means you don't need to redeploy the server in response to a change in client data requirements. This reduces a significant amount of the friction caused by frontend features needing to wait on backend deploys.
Other than that, you've got it 100%: GraphQL is a technology to make the Backend For Frontend pattern much easier and more flexible.
It ties in to the microservices architecture, I'd say.