rest attempts to solve interface normalization between services
graphql attempts to solve query normalization over a single api
they're as related as a vcr and a broadcast system - the problems they solve are adjacent, but do not overlap, and whereas their default sensible use is together, they can both be used without the other, or with alternatives to the other
> the problems they solve are adjacent, but do not overlap
I think this is just factually wrong. I've experienced many situations where exposing a GraphQL API, even when just intended to be called by another service, provided a number of advantages over a "plain REST" service, so we went with GraphQL, and I have seen other companies do the same. GitHub, for example, has a set of FAQs of "migrating from our REST APIs to our GraphQL APIs".
By "REST" I meant the way it's mostly used, so "REST API" to mean "HTTP API with maybe a notion of resources", since REST is the term people use to talk about these things.
In practice, what I've seen is GraphQL used where REST[0] would have been. I've not seen it used in any case where the solution wouldn't, previously, have been REST, or in a case for which there would otherwise have been no solution. They are, de facto, competing tech, from what I've seen. I expect there are some examples where that's not true, but I think as experienced by most people it's an alternative to REST.
[0] The colloquial sense of REST, that is, which is RESTish. Yes, I know, no-one actually does REST, for practically any value of "actually".
GraphQL can be seen as a programming language to write API endpoints, which you can expose as HTTP endpoints in a RESTful way if you want (or use a single POST endpoint, or use WebSockets).
In a traditional REST system you implement each API endpoint in a traditional programming language.
With GraphQL you first create a single GraphQL model and then write each API endpoint as a GraphQL query/mutation; often the code is in the source of the client apps and is extracted by the build system to generate the endpoints on the server.
It is also possible to let the client send arbitrary GraphQL at runtime to the server, although that's not recommended for security, performance and efficiency reasons.
In practice this means that if you change the client frontend to include different details in views (e.g. you decide to change a GraphQL-enabled HN so that the bio of the comment author is shown below every comment) then you only need to change the frontend and the GraphQL query (to include the extra data you need) and not the server backend code.
You're right, but I proposed that to get an idea on how big is GraphQL compared to other things present in the same space. GraphQL doesn't replace REST and they can leave together, but still, if there are as many searches/results for GraphQL than for REST, or 10 times more, or 10 times less, it would say a bit more about its position.
Stackoverflow mentions + Github repos created are both very imperfect proxies. Also, never show cumulative stats in a graph - it almost always go up and to the right: not insightful at all.
The problem with those metrics is they are laggy so may not show the trends being enacted today until a future date.
The 0.8 -> 1.4 may be a result of the hype cycle peaking, companies adopting a new tech, using it enough they need to hire people with it.
Or potentially now, companies not adopting this new tech with such a great rate because the hype cycle is over, graphql doesn’t get included in new projects, there’s no reason to hire someone for it in 6 months time.
> Also, never show cumulative stats in a graph - it almost always go up and to the right: not insightful at all.
I mean thats the definition of a cumulative graph... it basically has to go up and right. But thats ok. You can look at the slope of the cumulative graph to tell if its gaining steam or not. For example you can clearly see that the cumulative views on StackOverflow is flattening out, but the HN mentions is approximately a slope of 1
But if all you're interested in is the slope and the second derivative (which seems to be the case here), why not just graph the slope? With a cumulative graph, reading the slope is hard and reading the second derivative is even more difficult.
The only reason I can see to use a cumulative graph is if the total is actually what's interesting (for example, total covid vaccinations in arms over time). The total seems largely irrelevant in a discussion of hype cycles.
It seems like the only thing is 'graph what's actually interesting'? A 'cumulative graph' of dy/dx is just a y/x graph; i.e. whether what you're looking at it is 'cumulative' or not is just a matter of perspective of what the 'real' underlying thing is.
To use your COVID vaccinations example - is 'percentage vaccinated' that goes up and right cumulative? It is if we think of it as percentage that were being vaccinated at each unit x; but not if we think of it as being percentage that had been vaccinated at each x.
It'd be like saying Acceleration is 'a derivative', so show velocity instead. Everything's a derivative if you stand on the right side of it; everything's an accumulation/integral on the other.
One immediate reaction: this data isn’t adjusted for overall numbers. Yes, the number of GraphQL mentions on Hacker News varied, but how did it vary compared to the overall number of comments on the site? Same with SO questions and GitHub repos.
Without controlling for that you might just be looking at the normal ebb and flow of site traffic throughout a year. In fact you see it in the SO data, where both GraphQL and Kubernetes take a dive at the end of 2020. I’ll bet overall site traffic was down as people left for holidays, focused on end of year reviews, etc etc.
The post mentions all the data come from BigQuery so it should be relatively simple to get an overall row count. I'm not clued in enough on BigQuery pricing to know whether it would suddenly make the query uber-expensive, though.
I’ve looked up a lot of tech on Google trends. Something strange happened late 2020 across many tech topics. Searches are down across the board.
I can only speculate that people working from home just stopped working as much and therefore searched for work topics as much. Or maybe all the universities going virtual meant less students working as hard and searching for help less. It would need someone to give it some real research to uncover what caused the trend. But it’s super pronounced if you run some searches on google trends
I've only had a little experience with GraphQL, but I'm finding it frustrating because designers of the APIs tend to normalize structures since the backend is often a relational (or graph) database.
For example, rather than having top level "admin contact email" and "business contact email", API designers will have a sub graph of contacts, with label->email. (Note that this is the trivial example, it gets much worse)
Most of the time, I need a flattened version to actually do the work. Now, with SQL, that's not an issue because I can put a query together that flattens/joins as needed. But, with a GraphQL result withs lots of edges and nodes, I can't do that simply. I have to write some bespoke recursive walker to pull the data back up.
I understand I could fix this with the schema, but these aren't my APIs, I'm just a consumer. There doesn't seem to be some universally supported way to do the equivalent of a join.
Or, more simply, the culture around REST/JSON seems to prefer flatter structures, but the GraphQL crowd tends to like more nested structures...even when it's not really needed.
Edit: Also, it's not so simple to make a universal, declarative-driven "flattener", as the nested structures vary pretty wildly in how they are done.
We left out edges and nodes from our GraphQL API because of how confusing they are. But the downside is that we had to add a <collection>Stats object for each collection type to support meta data like the count. Still it seems to be easier this way for non-developers to learn. And the API consumers are mostly not developers, like account managers and accountants, usually via GraphiQL.
Fair point: GraphQL is mostly a data retrieval protocol that helps you retrieve specific data as stored by the app. SQL also provides data transformation with grouping, aggregations, functions, where clauses, views, subqueries, etc. You could implement that in the resolver, but then you're at the mercy of the api implementer.
You can use SQL in your resolver, like you mention. Note you’re also at the mercy of the API implementor if they use SQL in a REST endpoint.
GQL also has some affordance for renaming fields (although admittedly nothing like SQL for the client, if you did allow running sql via the client it would be harder to sanitize, so this is a “feature” not a “bug”)
I don’t align with your view, let me share my view.
The GitHub web hooks (which is basically REST) post a deeply nested json full of nodes (that you “might need”) which I don’t need, and lacking info I do need (ended up having to do another round trip to GQL after receiving the bloated web hook payload)
I have seen suboptimal APIs on both technologies.
If you don’t have control over the API, it doesn’t matter if it uses SQL, so following your logic the issue seems to be that you cannot change the API, not the tech it uses.
It's recommended to use nesting in GraphQL objects (both inputs and responses) for backward- and future compatibility.
But your problem is mostly because the API is not under your control.
In GraphQL backends it's OK to add special queries adapted for specific UI/UX (I think it's the whole idea behind the BFF - Backend-For-Frontend pattern).
I.e. you can choose between Design-first (data-centric) or Client-first (optimized for rendering on the Client/Front-end) GraphQL schema methodologies.
In the Client-first GraphQL schema you can have queries returning flattened data.
A non-standard approach is to run transformations, i.e. you specify directives how to transform the GraphQL operation responses. This can be for flattening, aggregations, calculating statistics, or joining results of the different queries.
GraphQL should have been called FacebookQL and microservices should have been called Netflix-services.
Otherwise hype-following developers think it's a good idea to just go ahead and use them, despite not having the unique needs and resources of neither of those megacorps.
With GraphQL, I can generate most of my client libraries while, and when I am writing a web client using typescript, I have full type checking on my apps. This makes me as a solo developer so much faster than using rest, with 0 client library generators, and 0 type safety. If my API changes response, my front end generated library will fail compilation with a type error.
Moral of the ramble, new tech is great – sometimes.
> With GraphQL, I can generate most of my client libraries while, and when I am writing a web client using typescript, I have full type checking on my apps. This makes me as a solo developer so much faster than using rest, with 0 client library generators, and 0 type safety. If my API changes response, my front end generated library will fail compilation with a type error.
> Moral of the ramble, new tech is great – sometimes.
You can do this with a boring REST API too. Most frameworks can automatically generate a swagger file, and there is a tool to generate clients from this in lots of different languages.
Another data point - user traffic to graphql.org has been flat since mid-2020 - at least according to Semrush - at about 250k visits per month. So it's a tech that people are using, but it seems to have saturated its use case.
We bought into the GraphQL vision on past projects but I came out the other end never wanting to work with it again. So much effort is put into trying to make "one API to rule them all". The shape of that API will always have inefficiencies, waste, and misaligned expectations about the data.
If you control the client the server then most likely your client has a function wanting data so just call a function on the server to provide it. A generic http-based abstraction in the middle isn't always the right answer.
Our most recent project is a SPA making RPC calls with a BFF* architecture. We couldn't be happier.
52 comments
[ 2.9 ms ] story [ 130 ms ] threadSounds to me like important questions, as a data engineer.
graphql attempts to solve query normalization over a single api
they're as related as a vcr and a broadcast system - the problems they solve are adjacent, but do not overlap, and whereas their default sensible use is together, they can both be used without the other, or with alternatives to the other
I think this is just factually wrong. I've experienced many situations where exposing a GraphQL API, even when just intended to be called by another service, provided a number of advantages over a "plain REST" service, so we went with GraphQL, and I have seen other companies do the same. GitHub, for example, has a set of FAQs of "migrating from our REST APIs to our GraphQL APIs".
REST is a philosophy while GraphQL is a spec. There is no "REST spec", HTTP isn't REST.
[0] The colloquial sense of REST, that is, which is RESTish. Yes, I know, no-one actually does REST, for practically any value of "actually".
In a traditional REST system you implement each API endpoint in a traditional programming language.
With GraphQL you first create a single GraphQL model and then write each API endpoint as a GraphQL query/mutation; often the code is in the source of the client apps and is extracted by the build system to generate the endpoints on the server.
It is also possible to let the client send arbitrary GraphQL at runtime to the server, although that's not recommended for security, performance and efficiency reasons.
In practice this means that if you change the client frontend to include different details in views (e.g. you decide to change a GraphQL-enabled HN so that the bio of the comment author is shown below every comment) then you only need to change the frontend and the GraphQL query (to include the extra data you need) and not the server backend code.
Edit: someone posted a comparative google trend in the thread: https://trends.google.com/trends/explore?date=all&q=REST,Gra.... That's the type of info I expected.
But in this case, you can clearly see the trend shift from the actual data anyway, so even that wouldn't really add anything.
A much better proxy is the % of job openings/companies that mention GraphQL in a job opening: https://pasteboard.co/KaZ2ko0.png
Both have increased from 0.8% to 1.4% YoY, and the demand for GraphQL skills have kept increasing for more than 2 years.
The 0.8 -> 1.4 may be a result of the hype cycle peaking, companies adopting a new tech, using it enough they need to hire people with it.
Or potentially now, companies not adopting this new tech with such a great rate because the hype cycle is over, graphql doesn’t get included in new projects, there’s no reason to hire someone for it in 6 months time.
I mean thats the definition of a cumulative graph... it basically has to go up and right. But thats ok. You can look at the slope of the cumulative graph to tell if its gaining steam or not. For example you can clearly see that the cumulative views on StackOverflow is flattening out, but the HN mentions is approximately a slope of 1
The only reason I can see to use a cumulative graph is if the total is actually what's interesting (for example, total covid vaccinations in arms over time). The total seems largely irrelevant in a discussion of hype cycles.
To use your COVID vaccinations example - is 'percentage vaccinated' that goes up and right cumulative? It is if we think of it as percentage that were being vaccinated at each unit x; but not if we think of it as being percentage that had been vaccinated at each x.
It'd be like saying Acceleration is 'a derivative', so show velocity instead. Everything's a derivative if you stand on the right side of it; everything's an accumulation/integral on the other.
Without controlling for that you might just be looking at the normal ebb and flow of site traffic throughout a year. In fact you see it in the SO data, where both GraphQL and Kubernetes take a dive at the end of 2020. I’ll bet overall site traffic was down as people left for holidays, focused on end of year reviews, etc etc.
They all seem pretty stable, although REST and RPC switched places in the mid-2000's
https://trends.google.com/trends/explore?date=2005-06-13%202...
I can only speculate that people working from home just stopped working as much and therefore searched for work topics as much. Or maybe all the universities going virtual meant less students working as hard and searching for help less. It would need someone to give it some real research to uncover what caused the trend. But it’s super pronounced if you run some searches on google trends
For example, rather than having top level "admin contact email" and "business contact email", API designers will have a sub graph of contacts, with label->email. (Note that this is the trivial example, it gets much worse)
Most of the time, I need a flattened version to actually do the work. Now, with SQL, that's not an issue because I can put a query together that flattens/joins as needed. But, with a GraphQL result withs lots of edges and nodes, I can't do that simply. I have to write some bespoke recursive walker to pull the data back up.
I understand I could fix this with the schema, but these aren't my APIs, I'm just a consumer. There doesn't seem to be some universally supported way to do the equivalent of a join.
Or, more simply, the culture around REST/JSON seems to prefer flatter structures, but the GraphQL crowd tends to like more nested structures...even when it's not really needed.
Edit: Also, it's not so simple to make a universal, declarative-driven "flattener", as the nested structures vary pretty wildly in how they are done.
Feels like something that came with a graph database, and people tried to blindly copy it.
Graphql code generator is great though. Absolutely wonderful. Makes it really hard to go back to rest.
GQL also has some affordance for renaming fields (although admittedly nothing like SQL for the client, if you did allow running sql via the client it would be harder to sanitize, so this is a “feature” not a “bug”)
The GitHub web hooks (which is basically REST) post a deeply nested json full of nodes (that you “might need”) which I don’t need, and lacking info I do need (ended up having to do another round trip to GQL after receiving the bloated web hook payload)
I have seen suboptimal APIs on both technologies.
If you don’t have control over the API, it doesn’t matter if it uses SQL, so following your logic the issue seems to be that you cannot change the API, not the tech it uses.
The difference is the culture/background/ecosystem around GraphQL, which makes it happen more often. It's the easy path there.
But your problem is mostly because the API is not under your control.
In GraphQL backends it's OK to add special queries adapted for specific UI/UX (I think it's the whole idea behind the BFF - Backend-For-Frontend pattern).
I.e. you can choose between Design-first (data-centric) or Client-first (optimized for rendering on the Client/Front-end) GraphQL schema methodologies.
In the Client-first GraphQL schema you can have queries returning flattened data.
A non-standard approach is to run transformations, i.e. you specify directives how to transform the GraphQL operation responses. This can be for flattening, aggregations, calculating statistics, or joining results of the different queries.
https://www.graphql-mesh.com/docs/getting-started/mesh-trans...
Otherwise hype-following developers think it's a good idea to just go ahead and use them, despite not having the unique needs and resources of neither of those megacorps.
Moral of the ramble, new tech is great – sometimes.
https://www.graphql-code-generator.com
> Moral of the ramble, new tech is great – sometimes.
> https://www.graphql-code-generator.com
You can do this with a boring REST API too. Most frameworks can automatically generate a swagger file, and there is a tool to generate clients from this in lots of different languages.
If you control the client the server then most likely your client has a function wanting data so just call a function on the server to provide it. A generic http-based abstraction in the middle isn't always the right answer.
Our most recent project is a SPA making RPC calls with a BFF* architecture. We couldn't be happier.
* https://samnewman.io/patterns/architectural/bff/