return to table of content

After 6 years, I'm over GraphQL

atsjie
174 replies
11h31m

Worked on two GraphQL projects; I was quickly cured from the hype. I recognize a lot of points in this article.

In both these projects the GraphQL had started small. I came in during a more mature phase of these projects (2 and 4 years). That's where the requirements are harder, more specific, and overall complexity has grown. Adoption and demand on the API were growing quickly. Hence you logically spend more time debugging, this is true for any codebase.

But GraphQL has everything in it to make such problems even harder. And both these projects had clear signs of "learning-on-the-go" with loads of bad practices (especially for the N+1 problem). Issue descriptions were much vaguer, harder to find in logs and performance issues popped up in the most random places (code that had been running and untouched for ages).

Fun fact; in both these projects the original devs who set it up were no longer involved. Probably spreading their evangalism further elsewhere.

RPC and REST are just more straightforward to monitor, log, cache, authorize and debug.

matt_s
106 replies
8h28m

RPC and REST are just more straightforward to monitor, log, cache, authorize and debug.

REST API's are a proven solution for the problem of other apps, including front-ends, needing data from a data store. Using JSON is much improved over the days of XML and SOAP. Beyond that there haven't been advancements in technology that cause fundamental shifts in that problem space. There have been different opinions about structuring REST calls but those aren't going to cause any real forward progress for the industry and are inconsequential when it comes to business outcomes.

There are so many developers out there that can't stand plugging in proven solutions to problems and just dealing with the trade-offs or minor inconveniences. Nothing is going to be perfect and most likely a lot of the software we write will cease to be running in a decade.

hansonkd
87 replies
7h36m

REST APIS suck for nested resources. GraphQL is a huge breakthrough in managing them.

Ever seen an engineer do a loop and make n+1 REST calls for resources? It happens more often then you think because they don't want to have to create a backend ticket to add related resources to a call.

With internal REST for companies I have seen so many single page specific endpoints. Gross.

There have been different opinions about structuring REST calls but those aren't going to cause any real forward progress for the industry and are inconsequential when it comes to business outcomes.

You could argue almost any tech solution in a non-pure tech play is largely in consequentially as long as the end goal of the org is met, but managing REST APIS were a huge point of friction at past companies.

Either it goes through a long review process to make sure things are structured "right" (ie lots of opinions that nobody can sync on) or people just throw up rest endpoints willynilly until you have no idea what to use.

GraphQL is essentially the "Black" for Python Syntax but for Web APIs. Ever seen engineers fight over spaces vs tabs, 8 vs 4 spaces, whether a space before a colon? those fights happened a lot and then `black` came out and standardized it so there was nothing to fight over.

GraphqL makes things very clear and standard, but can't please everyone.

kiney
30 replies
7h21m

Unpopular opinion: I'm actually a fan of singe page specific endpoints. You get much easier debugging, easier to audit security, easier performance optimization an the imho pretty small price to pay is that it's "not elegant" and a bit of backend code

marcosdumay
12 replies
5h30m

The modern web development practices are just insane.

The GP's idea that a frontend developer would send a ticket to somebody so they can get all the data they need... it's just crazy.

On the other extreme, we have the HTTP 1.0 developers saying something like "networks are plenty of fast, we can waste a bit of it with legible protocols that are easier to make correct", while the HTTP 2.0 ones are all in "we must cram information into every single bit!"

Every place you look, things are completely bananas.

klibertp
11 replies
4h48m

idea that a frontend developer would send a ticket to somebody so they can get all the data they need... it's just crazy.

For me, what's crazy is that there are "web" developers who can't just add the endpoint they need while working on a frontend feature, or "web" developers who can't just add an element or a page for testing the backend endpoint.

What ever happened to full-stack developers? The "frontend" and "backend" developer split is so incredibly inefficient that it's really jarring—you take something that should take 2 hours and magically, through tickets, delegation, and waiting for results (then repeat that for debugging, who knows how many times!), make it into a 2-3 day task.

I once reproduced (black-box style!) a two-week effort by a three-man team in six hours of work simply because I had PyCharm and IDEA opened side-by-side and could write code on both sides at the same time.

If someone has a good explanation for why the full-stacks that were once the norm went almost extinct, I'd be happy to give it a read!

GeneralMaximus
4 replies
3h57m

For context: I work on large-scale browser apps that are closer in complexity to something like Linear or Obsidian than to your standard WordPress blog with some forms. E.g I'm currently working on a browser-based GIS tool for the financial sector.

I started my career as a full-stack developer, but went all-in on frontend because I felt I was spreading myself too thin. At one point I found that I could choose to be almost good enough at doing two different things or extremely good at one thing. I chose the latter option.

Modern browser apps are complex beasts, at least if you want to do them right. You obviously have to worry about all the technical bits --- HTML, CSS, JavaScript, your view library of choice, platform APIs like <canvas> and WebAudio, cross browser testing, bundle sizes, performance optimizations, techniques like optimistic rendering, all that good stuff.

On top of that, you also need to work closely with designers to make sure they know the features and limitations of the platform(s) they're designing for. More often than not, you end up being a sort of bridge between the backend devs, designers, and product managers.

A lot of times you end up doing design too, whether you like it or not. I've learned a lot about UI/UX design just because I often have to fill in the gaps where a designer forgot to include a certain error state, or didn't test their design on tablet screens, or didn't account for cases where a certain API might not be available.

I tried for many years to learn as much as I could about Django as well as React and friends. But it eventually got too much. I found that I wasn't able to keep up with both ecosystems, and I was producing code that wasn't very good. I could certainly build things quickly because I was familiar with all parts of the stack, but it came at the cost of code quality, security, stability, and robustness. I eventually decided to hang up my backend developer hat and focus exclusively on what goes on inside the browser (which can be a lot by itself these days!)

It's probably possible for a single individual to build a high-quality server-rendered MPA with some forms without making a mess of it. But that says more about how good Rails/Django/Laravel are than about the capabilities of any single individual. I don't think a single person could build a product like Linear end-to-end without cutting corners.

int_19h
1 replies
3h31m

IMO the fact that being a full-stack dev is so taxing is an indication that the stack as a whole is just way too complex and overengineered. Which is rather obvious from looking at the state of affairs on the frontend side of things. Desktop GUI devs don't usually have those problems.

mc10
0 replies
41m

I don’t think this is a fair conclusion; web development is harder than desktop GUI development for various reasons.

For one, clients (mobile, desktop) are drastically different with all sorts of downstream implications:

- Differing screen size requiring responsive design

- Internet speeds magnitudes different

- Intermittent internet

- Uneven feature support due to different versions of browsers

- Everything needs to be JS at the end of the day

Desktop apps generally don’t have to worry about any of these issues.

Also, desktop GUI frameworks are typically either fragmented (one per OS) or don’t look OS-native.

evantbyrne
0 replies
3h29m

I don't think the claim is that a single developer should be able to build an entire enterprise product, but rather that a single developer should be able to implement the software side of a task end-to-end. The latter is a reasonable expectation when your software is monolithic.

apsurd
0 replies
3h33m

... I don't think a single person could build a product like Linear end-to-end without cutting corners.

Cutting corners is a feature. I bet the Linear team is as pained as any, internally, at the tradeoffs they're making.

There is no way to know "what to get right" without going through it. So for 80% of the dev cycle the job is to cut corners to get to the 80/20, rinse and repeat forever.

This isn't against excellence and the dream of a beautiful product experience as your reply seems to convey.

riffraff
2 replies
4h31m

Because people have a limited appetite for complexity.

I wrote some front-end stuff back in the days but I've lost track of whatever is happening these days. jQuery to append some stuff took five minutes to learn, but learning react hooks takes a determined effort.

Likewise, adding a field to a graphql type is simple, but doing it with authorization, controlling n+1s, adding tests etc.. requires front-end folks to actually invest time in learning whatever back-end they're dealing with this time.

Everything is just a lot more complicated these days, and if you've been around for a while you may not be excited anymore by the churn, but rather fed up.

jack_riminton
1 replies
3h24m

This is why the Rails community should be applauded in my book, for their dogged determination that we should keep it a “one person” framework. Yes it may not be as performant, type safe or flashy on the front end but my god it’s productive.

At my startup there are 7 devs who can all do tickets across the stack and as we grow I think it would be good if we could resist the pressure to silo and specialize

ethagnawl
0 replies
1h19m

but my god it’s productive.

It really is. Regrettably, I've drifted away from it in large part because of client requirements for more "modern" and "maintainable" solutions (e.g. Python or Node; I'll take Python every time, thanks). Django comes very close in terms of productivity (and is better in some ways: auth, admin, etc.) but the Rails CLI, generators and community (not sure if this is still relevant) give it the edge.

The "recent" (last 10+ years) movement towards "lightweight" libraries (instead of frameworks) that require you to either reinvent the wheel, copy-and-paste or use some random "getting-started" template every time you start a new project is disheartening. As others have said above, I think it's partially resume-driven-development and people wanting to tinker (both of which I do appreciate).

Something which continues to surprise me is that there hasn't really been a "modern" successor to Rails. Granted, I haven't kept pace with developments in the Node/TypeScript world but, last time I looked, Sails was on the right track but wasn't very actively developed and I was shot down (in favor of Express spaghetti) when I suggested it. There's also a smattering of Rust web frameworks but none that quite fit the bill and come with all of the batteries and opinions included. I keep saying I'm going to do a Summer of Code project which attempts this but ... life.

marcosdumay
0 replies
4h13m

If you absolutely need 2 people for that, they should be side by side.

But yes, that break-down of the problem is insane. People artificially split an atomic problem in two, and go create all of that extra craziness to try to solve the communication problem they made.

And then people go and push UX and UI tasks into the frontend developer, and ops tasks on the backend since them are there... What is insane again, because those are really incompatible tasks that can't be done with the same mindset.

And since it's standard, backend tools won't support the frontend and the other way around. So the insanity gets frozen on our tooling.

evantbyrne
0 replies
3h14m

Microservice architectures and the associated explosion in complexity on both ends are to blame. When it takes twice the time to build something, it is natural to hire twice as many developers. Increased complexity drives specialization.

defen
0 replies
3h19m

Many organizations would rather pay 3 people $120,000 each instead of paying 1 person $300,000 to do the same work, for a variety of reasons. Some good, some bad.

WD-42
8 replies
6h35m

Yup. Especially when your api really only has 1 (possibly 2 in the case of a mobile app) real clients. People like to pretend their apis are generic but they aren’t. There’s a good argument to stop writing generic apis for your single application.

hansonkd
7 replies
6h30m

Typically the endpoints clients are multiple frontend developers. If the frontend is blocked for every page they need waiting on the backend to expose data that massively increases the costs of features and reduces the time for delivery.

WD-42
3 replies
6h27m

This happens anyway.

hansonkd
2 replies
6h21m

Not nearly as often with Graphql and happens less and less as your backend and data models stabilizes.

Most of our frontend features now don't have backend changes and we were able to increase the ratio of frontend to backend devs.

blowski
1 replies
5h29m

My experience is that the problem is avoided in theory, but not in practice.

Making a good API on a large system with many clients is always difficult. GraphQL makes it easier in theory, but if you have average level devs working on it, they’ll make a bigger mess than if they use simple REST. The latter will still be complex, but at least it’s easier to have observability.

ethbr1
0 replies
4h56m

Aka never underestimate the power of additional complexity to drive bad use, absent familiarity.

bunderbunder
2 replies
5h24m

This sounds like more of an org chart problem or a value chain management problem than a technical problem.

throwup238
1 replies
5h3m

That's why we have Conway's law.

bunderbunder
0 replies
2h38m

Yeah. And a gentle nudge that Conway's Law is about lines of communication in general, not specifically the org chart.

I used to be in charge of the stored procedures that served as the API to a shared database system used by many teams. (So, not exactly the same thing, but I'd argue that the sprocs vs ORM debate isn't entirely dissimilar from the REST/RPC vs GraphQL debate.) My turnaround time for getting database API changes into staging for application teams to play with was typically less than one work day. But that happened because I had a lot of latitude to just get things done, because the company valued rapid delivery, and therefore made sure we had what we needed to deliver things rapidly, both from a technical and a business process perspective. This was in a very highly regulated industry where every change required paperwork that would be audited by regulators, too.

I've also worked at places where this sort of thing took ages. Typically the worst places for work backing up were organizations that used Scrum, because the whole "sprints" thing meant that the _minimum_ time to get something from another team was about 1.5 times the sprint duration. And even then you could only manage that if you could deliver a request that already met all of that particular team's requirements for being able to point it, and could convince their Product Owner that it was a higher priority than whatever their pet project is this quarter, and the stars align so that you perfectly time the submission of your request with respect to that team's Scrum process's frame rule.

The thing I want to point out here is that absolutely none of that bullshit was ever the API technology's fault.

datavirtue
2 replies
6h48m

Agreed. Specific endpoints. I was on a project recently where a 40+ yr old dev was going crazy over "pure REST." It's embarrassing. Sure, have your pure REST but FFS create specific endpoints if you they make sense.

mgkimsal
1 replies
6h35m

You are literally Transferring the REpresented State of a given page/view/screen.

Screen-specific REST endpoints will make their way as a default in to a JS-based framework in 2025 and people will pretend like this is some breakthrough advancement.

mjburgess
0 replies
6h19m

And finally HyperText will progress into the futuristic HyperCard

nurple
0 replies
7h0m

I think it's elegant. I loved MVVM in the postback world, and with SPAs, I see view-specific endpoints as the view-model continuing to reside on the server while the view was split off to the client-side.

eddd-ddde
0 replies
3h25m

This is the true purpose of REST. If you need to make multiple requests for a single operation you don't have enough endpoints.

The idea that resources and the underlying data needs to map 1-1 is wrong.

charlie0
0 replies
1h20m

Sounds good in theory. In practice, what I've seen is people don't just do single page endpoints with shared services, they follow this all the way down into the services and so you end up with lots of duplicate looking code. This isn't a problem until the application gets big enough and now you have business logic that should be the same spread out across an app. This leads to weird bugs where something that should work the same way doesn't depending on which page you're accessing things from. Of course, I don't a solution, solving things like this is what makes software engineering hard.

blowski
0 replies
5h35m

I’ve heard this called the “backend-for-frontend” pattern.

ComputerGuru
25 replies
7h26m

With internal REST for companies I have seen so many single page specific endpoints. Gross.

Hardly gross. It is what it is and it’s universal across the domain. I bet Windows has internal APIs or even external ones that were created just for one page/widget/dialog of one app. It’s the nature of things at times.

hansonkd
19 replies
7h20m

Its gross because it is a waste.

An engineer had to spend time to make that specific API for that page instead of the frontend consumer using what was already defined and get all the resources with one call and 0 backend engineer needed for that new page.

RVuRnvbM2e
11 replies
6h24m

That backend engineer wrote a single SQL query that joined some tables, ensured indices were used, and always executed in <1ms.

In graphql land you'd be doing multiple SQL queries, "joining" in the API layer, and spending 50ms per API call.

chuckadams
6 replies
6h3m

The entire point of graphql servers is that they're basically ORMs (or use an underlying ORM) that turn complex nesting into a single query's worth of joins. It won't beat hand-crafted sql from an expert, but if that's your preferred approach, debates on the relative merits of different query frameworks are all academic to you anyway.

RVuRnvbM2e
5 replies
5h54m

I've never seen this kind of graphql server implementation that can automatically boil down a complex nested query to sensible SQL. It sounds like the best of both worlds. Do you have links?

hansonkd
3 replies
5h45m

Typically libraries use a Dataloader + ORM to implement this which gets you pretty far, outside of that some libs like Strawberry with automatically optimize your queries for you if you return Django ORM Querysets.

Any query you were going to build and serve with Rest can be made with these two methods or even a raw dataloader and manual SQL string.

discreteevent
2 replies
5h29m

The inventors of GraphQL did not intend it to be mapped directly to a database.

"That would be one way to implement the system in a DB-centric way. However we believe that intermediate application code is pretty critical to any GraphQL implementation." [1]

"GraphQL is a client-server dance that needs server-side capabilities, not just CRUD semantics." [2]

[1] https://news.ycombinator.com/item?id=9879870

[2] https://news.ycombinator.com/item?id=14351800

hansonkd
1 replies
5h14m

The Language Libs like Strawberry implement what he is describing by intermediate application code. It doesn't map directly to a database.

GQL implementations don't map to the database but to application code.

chuckadams
0 replies
4h34m

Specifically, GQL implementations always map to a `resolve(source, args, context, info)` function (the names can be anything, the types are what matter). In that sense, you also get a standard server interface similar to wsgi/psgi/rack, but much more fine-grained (there can be a resolver for every field in the query).

chuckadams
0 replies
5h1m

Symfony API Platform boils to ORM-generated SQL via Doctrine, which is verbose, but not overly clever. So the only link I could give you there would be to the Doctrine query builder docs (I won't subject you to API Platform's docs). I imagine a more sophisticated graphql dialect like what Prisma supports can generate some pretty gnarly sql, but that's ORMs for you. But exposing your data model directly through graphql is also not recommended, same with REST APIs (I can't claim the high ground, my biggest graphql project exposes models directly. The tradeoff was worth it in this case). So in the end you're writing custom controllers/resolvers anyway, and field resolvers are where graphql really starts to shine.

hansonkd
3 replies
6h17m

What? GraphQL is purpose built to solve that in 1 Query. Not doing it in 1 query is on you not the protocol.

In practice with REST the frontend engineer didn't want to wait and tried to use the existing REST endpoints, did N+1 API HTTPS calls and then joined them client side in javascript.

fiddlerwoaroof
1 replies
6h2m

A lot of graphql implementation end up moving the n+1 problem to the query resolver.

hansonkd
0 replies
5h56m

Every GQL implementation I have seen explicitly has a way to avoid n+1 queries.

RVuRnvbM2e
0 replies
5h58m

What? GraphQL is purpose built to solve that in 1 Query. Not doing it in 1 query is on you not the protocol.

1 graphql query maybe. But that translated to a dozen SQL queries.

In practice with REST the frontend engineer didn't want to wait and tried to use the existing REST endpoints, did N+1 API HTTPS calls and then joined them client side in javascript.

The point you're missing is that for 1 graphql query the API did N+1 SQL queries, and then also joined them in JavaScript.

In the REST case the front end can switch to the efficient custom endpoint when it is implemented. In the graphql case it will never get any faster because the API has to stay generic.

arp242
2 replies
4h53m

This is like, an hour per endpoint. For maybe 30 endpoints (high figure for many apps) throughout the lifespan of your application. But let's say 3 hours: you're talking about 90 hours in total, over a period of 2 or more years. It's really not that much.

And GraphQL isn't free either; you need to actually implement that. It pervades your entire stack, too – it's not something you can just "put on top of it".

I think that in many cases, perhaps even most, GraphQL is a "spend 8 hours to automate a half hour task" kind of affair. Are there cases where that's not the case? Probably. Maybe your specific use case is one of them. But for the general case? I'm entirely unconvinced.

hansonkd
1 replies
4h8m

An experience engineer knows that a change that takes hour turns to days when a team is running at scale and needs to have CI approvals etc.

Why waste any time?

And GraphQL isn't free either; you need to actually implement that

Rest isn't free. You have to actually implement also that and end up with a more limited API.

GraphQL libs in Python are equally as complex as the FastAPI etc..

arp242
0 replies
3h30m

And no one will be spending days working on it, they will work on other things while waiting for code reviews and such.

GraphQL libs in Python are equally as complex as the FastAPI etc.

You need to account for the fact that anything can query anything, whereas a more traditional REST-type API will have much more limited codepaths.

This starts with just basic database maintenance and indexing, which in many case will be significantly more complex, to all sorts of other problems. This article already enumerates them so I'm not going to repeat them here.

You can't just handwave all of that away with "oh there's a library you can use".

If you think all of that is worth it then that's fine. As with many things it's a trade-off, and a bit of a judgement call too. But please, don't pretend this complexity doesn't exist, and that the trade-off doesn't exist.

clintonb11
1 replies
7h5m

Is the flexibility worth the tradeoffs? Maybe in a company where you are adding new pages all the time with deeply nested relational data needs. But I would argue this is more rare than not. And I often find that frontend engineers aren’t as familiar with database queries and the load they are putting on the system with some of the graphql queries they are making. Flexibility for frontend has its own tradeoffs and I totally understand why a frontend engineer doesn’t want to have to wait for an endpoint to be finished. But this article outlines some of the issues you encounter later as you scale your team and system.

We use a schema first design where I am at and if a frontend person needs a new endpoint because the resource-only endpoints aren’t enough then they submit a pull request to the schema repo with a design for their endpoint they need. It gets approved and boilerplate is auto generated. Yes you have to wait longer, but 90% of the time (for our software) the resource endpoints work great.

hansonkd
0 replies
6h54m

Sorry what are the tradeoffs?

I'm not sure where this narrative comes from that GraphQL immediately means that the frontend time will have no idea what they are doing and will induce load on the system.

95% of my nested graphql fields are based on foreign key indexes so its almost no additional load to the system (only 1 query per "level" of GraphQL) to query the nested objects.

I restrict GraphQL to 5 levels and now I have 5 queries per API call instead of 5 Queries over 5 API calls.

The backend team exposes the fields that they know are efficient to query. They can restrict the depth of the GraphQL, number of fields, etc.

vbezhenar
0 replies
1h32m

Every page is special. Using generalized API is waste of resources. Generalized APIs are hard to use and develop. It takes a genius to create a good generalized API (say SQL) and even those generalized APIs are not usable in web context (because of authorization and DDoS issues).

It's better to think about optimizing of creation specialized APIs.

pavel_lishin
0 replies
6h50m

On the other hand, it may take that engineer less time to create a page-specific endpoint than it would be to create something more generic that might serve other purposes (that may never come to pass), which may also involve talking to other teams, checking what future plans are, etc.

And that's assuming it's a new endpoint; if there's an existing endpoint that does almost what's necessary, they may need to check in with that team about what modifications to the endpoint would be acceptable, etc.

Single-page endpoints aren't great, but often times they're acceptable because they end up being a half-day task instead of a week-long slog.

datavirtue
4 replies
6h46m

It's analogous to a specific method in code. No idea why people go nuts over this.

hansonkd
1 replies
6h29m

A REST endpoint can be analogous to a specific method in code. just as much as a GraphQL field.

What people are excited about is that the frontend can request all the data it needs at once and the backend can efficiently serve it. Something not possible with REST without reimplementing something similar to GraphQL.

RussianCow
0 replies
1h19m

It's definitely possible, just not without tight coordination between frontend and backend. When your development teams are broken into silos with strong separation, this isn't feasible and GraphQL starts to make some sense. Otherwise, you just create an ad hoc endpoint that serves the exact data you need and call it a day.

svieira
0 replies
2h8m

I suspect that people don't think about it too hard and presume that they should have only one model - that is that their REST model should map directly to their DB model which should map directly to their internal domain model (the idea that there might be two-or-more-domains and not-all-of-them-are-public hasn't even yet crossed their minds).

When you realize that sometimes your REST model may be a view-model that maps to a different storage model optimized for online-transaction-processing, neither of which map to your internal domain model directly (there are adapters for that) _then_ you get somewhere ... but of course you then have to fight off the `transformToRestModel(transformToDomainModel(retrieveDbModel(theId)))` when the three models happily coincide for a time.

arp242
0 replies
4h59m

Some people treat codebases as an art project rather than engineering project.

I think this explains about three quarters of all engineering problems I've seen in corporate context, give or take.

realusername
16 replies
6h40m

With internal REST for companies I have seen so many single page specific endpoints. Gross.

Single page endpoints is exactly what you want if you have more than 5 engineers in your company anyways.

It ensures that the endpoints are maintainable and future-proof when people are working on different features.

hansonkd
15 replies
6h12m

It ensures that the endpoints are maintainable and future-proof when people are working on different features

How does GQL prohibit this? It encourages it by focusing on 1 stable API for everyone instead of a custom API endpoint for each case.

randomdata
7 replies
5h29m

It doesn't. That's literally what GraphQL was designed for: To provide a resolver that sits between high latency clients and all of the various REST/RPC services in order to roll up all of the requests at datacenter speeds into one in order to overcome the latency issues.

But you still need all of the various single page REST/RPC endpoints to make use of GraphQL as it is intended. Some developers out there skip the REST/RPC part, making GraphQL their entire service, violating its principles.

If it works it works, but it does not come tradeoff free.

hansonkd
6 replies
5h26m

? why do you need a REST endpoint with GraphQL? Nearly every language has a GraphQL engine that integrated directly with the database and exposed functions as GQL directly without REST at all.

randomdata
5 replies
5h12m

You don't, obviously – we already talked about how many don't. But if you don't have a graph of "microservices" in which to query, what do you need GraphQL for? Especially if all you are doing is returning the results from a database. The database will already have its own API. Why not just use it? The native API is always going be better than your attempt to translate.

hansonkd
4 replies
4h59m

Because exposing your Database to the outside world is asinine. GQL sits between letting the frontend query semi-customizable queries and not having any customizability to select related resources.

randomdata
2 replies
4h47m

Nobody said you should expose your database to the outside world. Do you not understand the difference between APIs and services?

hansonkd
1 replies
4h14m

You said

The database will already have its own API

Where is this API coming from? You have to build it. I'm saying you should make those APIs graphql apis though a language framework and not REST apis because GQL consuming GQL is much better than GQL consuming REST.

randomdata
0 replies
4h2m

Someone has to build it, but as long as you are using a popular DMBS the work is no doubt already done. All you need to do is stick your application-y bits in the middle – same as you have to do with GraphQL. Computers aren't exactly magic. It's all just 1s and 0s at the end of the day. You can do just about anything and make it work. But there are tradeoffs to different approaches. If GraphQL is the best choice for working with databases, why don't DMBSes use it natively?

int_19h
0 replies
3h12m

I'm curious as to why you believe that exposing direct SQL over the database is "asinine" but GQL is fine, given that either one is very generic, and e.g. the security issues are very similar (as the article points out).

realusername
6 replies
5h22m

I don't think it would hold true for very long, devs will have specific cases which will pile into the definitions.

That's why GraphQL examples usually focus on querying data from users and not how you are going to manage 10 different views of the same data.

hansonkd
5 replies
5h17m

pile into the definitions

That is how REST works but is the opposite of the way GQL works.

You don't pile into existing defintions but extend the current definitions out. A team needing new data doesn't affect the consumption of other teams. which is not the case of REST where if one team needs to change a REST endpoint to return different shape of data, they have to verify the new shape with other teams.

realusername
4 replies
4h56m

With REST, the endpoints are team based if you have even a semi-competent CTO so you never have this problem, you just check who owns the controller and that's it.

With GQL though, good luck retracing who owns what field and what does it affect if you change the definition of what it returns, especially that you you are not even using it on the same language.

Bonus points here if you are managing something outside of your control like a mobile app.

hansonkd
3 replies
4h49m

GQL you would only care about if someone removed a field not if someone added a field. How would adding a field change existing GQL calls return? Doesn't make sense.

Also, Its about 1 line to set up CI to extract all GQL queries from a typescript project and do static analysis to check against the schema.

But again you only care if someone deletes a field, and even if you have to delete it, at least the GQL schema has built in annotations for deprecation, something not in REST.

realusername
2 replies
4h31m

Deleting things happens all the time though.

Yeah sure you can make it work with anything if you spend the extra effort but the ownership really isn't as defined as in REST.

Is there code which have fuzzy or no ownership? Are there changes which affect other teams? Suddenly those became much harder questions to answer.

hansonkd
1 replies
4h13m

Actually deleting happens rather rarely compared to adding.

Its much easier to trace and debug what teams are using GQL fields than REST. What if one team is piggy backing on another teams exising rest endpoint and you dont know? same problem that would require some analysis of all code calling and endpoint to determine if a field is safe to delete. GQL makes this much simpler than REST.

realusername
0 replies
3h57m

On one side you need to check which folder you are in, on the other side you need to do a static analysis of the whole current and past apps.

I know there's some diverging opinions here but there's one which sounds definitely easier than the other.

As for deletes, I work in a company with a good hundred devs so that happens weekly at least.

theptip
6 replies
6h44m

The canonical REST solution of query params to add nested fields gets you quite far:

GET /myresource?extra=foo,bar

sure you over fetch a bit if you have multiple accessors.

But agreed, if you have highly nested data especially when accessed with multiple different query purposes then REST might not be the best fit.

I think GraphQL has been positioned as a general purpose tool and for that I am with the author, REST is a better go-to for most usecases.

hansonkd
5 replies
6h41m

I guess depending on the context of a simple app one level could be viewed as far.

Any more levels and you have now reinvented GraphQL

WorldMaker
2 replies
4h31m

OData existed before GraphQL in the wild, it's possible to suggest GraphQL reinvented OData.

https://www.odata.org/

hansonkd
1 replies
4h16m

The point is GQL is currently the standard for querying dynamic nested data shapes not that it is the first or was the first.

Look at OData download stats on Pypi it had 2 downlaods the last day. Graphql-core for python? 624,201. that is not even on the same planet.

If you don't use GQL and want a system of querying nested data you will be using a less used protocol that is analogous to GQL so you might as well use the standard.

WorldMaker
0 replies
2h42m

OData is still currently a standard for querying (among other things) nested data shapes. The point was it is a matter of fact that as a standard it predates GraphQL and as a matter of ecosystem perspective whether or not you think it is a more or less used protocol.

To trade anecdotes for anecdotes: On Nuget, the Microsoft.Data.OData package marked deprecated and marked with CVEs for critical bugs still has an average of 36.3K per day downloads. (Its successors combine for about double that.) The top GraphQL library (of the same name, unadorned) still only has 9.3K per day downloads. In .NET if you want a system of querying nested data (that is also "REST compatible"), why would you use a less used protocol like GraphQL?

eadmund
1 replies
2h29m

Any more levels and you have now reinvented GraphQL

Sure, but reinventing the wheel can be good, particularly when the existing wheel technology is oblong, lumpy and constructed of stone and cheese.

I’m just bitter than GraphQL endpoints return 200 on errors. If you’re returning 200 on errors, then you’re not really doing HTTP; you’re just using HTTP as a substrate for some other protocol, in which case you might as well just open a port and serve that protocol directly and not pretend to be HTTP.

vbezhenar
0 replies
56m

you’re just using HTTP as a substrate for some other protocol, in which case you might as well just open a port and serve that protocol directly and not pretend to be HTTP.

Browser does not allow to access any ports with any protocols.

Often intermediate software gets in the way as well. For example with Kubernetes it's trivial to expose HTTP service using Ingress and it's not trivial to expose other protocols.

Another HTTP plus is that it's trivially secured by TLS and every developer knows API for that. Using TLS for your own protocol or QUIC is absolutely not trivial and probably more like arcane knowledge.

karmakaze
1 replies
6h40m

One place I was at we used REST with a hydration service that ran as a proxy in front of the requests. That gave us most of the benefits of GraphQL and we only implemented it for the main resources (users, photos, and maybe one other thing). To minimize latency/faults the hydration service ran locally on every webapp/API server. I wasn't around for far too long after though to see how it turned out as it grew (if it did at all, the company sort-of went defunct--development-wise anyway).

I also recall, we had similar N+1 query problems in the REST API endpoints irrespective of hydrating the returned resources.

The biggest benefit of GraphQL I can see from a user perspective is that it lowers total latency especially on mobile with fewer round trips.

bernawil
0 replies
5h56m

you don't think it's a benefit that you could get the benefits of a "hydration service that ran as a proxy in front of the requests" out of the box?

there's lots of other benefits for GQL: multiple queries per request, mutation/query separation, typed errors, subscriptions support.

mvdtnz
0 replies
2h11m

With internal REST for companies I have seen so many single page specific endpoints. Gross

That's an established pattern (backend for frontend). Like all patterns there are trade-offs and considerations to make, but it's certainly not a priori "gross".

https://learn.microsoft.com/en-us/azure/architecture/pattern...

matt_s
0 replies
4h13m

If an app's API requires more than a couple of nested structures then, without knowing the specifics of the domain, I would venture a guess at a poorly defined data model is the issue vs. API technology.

For example, a lot of times people build out nice normalized table structures for online transactional apps. The UI/UX is pretty straight forward because end users typically only CRUD an object maybe a couple nested objects at a time. The API's are straight forward as well, likely following single responsibility principles, etc. Then comes along requirements to build UI's for analytics and/or reporting types of things where nearly the entire schema is needed depending on what the end user wants to do. Its the wrong data model for doing those types of things. What should be done is ETL the data from the OLTP schema into a data warehouse style schema where data is de-normalized so that you can build reporting, etc.

billisonline
0 replies
3h55m

Ever seen an engineer do a loop and make n+1 REST calls for resources? It happens more often then you think because they don't want to have to create a backend ticket to add related resources to a call.

With internal REST for companies I have seen so many single page specific endpoints. Gross.

As someone pointed out in reply to another comment, GraphQL is "a technological solution to an organizational problem." If that problem manifests as abuse of REST endpoints, you can disguise it with GraphQL, until one day you find out your API calls are slow for more obscure, harder to debug reasons.

WorldMaker
0 replies
2h48m

Ever seen an engineer do a loop and make n+1 REST calls for resources? It happens more often then you think because they don't want to have to create a backend ticket to add related resources to a call.

With REST, though, that pain is visible to both sides. Frontend engineers generally don't want to make N+1 REST calls in a tight loop; it's a performance problem that they see and that is very visible in their Dev Tools. Backend engineers with good telemetry may not know why they get the bursts of N+1 calls that they see without asking the Frontend or digging into Frontend code, but they can still see the burstiness of the calls and have some idea that something could be optimized, that something is maybe too chatty.

There are multiple ways with REST to handle things: pagination, "transclusions", hyperlinks, and more. Certainly "single page endpoints" is a way as well, no matter how gross it is from REST theory, it's still a pragmatic solution for many in practice.

REST certainly can please everyone, given pragmatic compromises, even if it isn't very clear or standard.

cess11
9 replies
6h4m

JSON winning over XML is like saying CSV won over MySQL. They aren't equivalent.

Much like CSV, JSON isn't particularly standardised and different parsers and writers will do different things in some situations. Usually it doesn't matter, but when it does you're probably in for a lot of pain.

If you handle structured data and the structures might change over time, JSON isn't a good fit. Maybe you'll opt for JSON Schema, maybe that'll work for your use case, but with XML you can be quite sure it'll be reliable and well understood by generations of developers.

The tooling is generally very good, commonly you can just point your programming language to the XSD and suddenly you have statically typed classes to program against. Perhaps you'd like to store the data in a RDBMS? You can probably generate the DB schema from the XSD. If you want you can just throw JSON into MongoDB instead, but there will be very important tradeoffs. Same goes for UI, you can write some XSLT based on the XML schema and suddenly you get web views directly from API responses. Or you could use those classes you generated and have your GUI code consume such objects.

None of this is as easy with JSON as it is with XML, similar to how many things aren't as easy with CSV as with a RDBMS.

svachalek
4 replies
5h51m

What's missing in ECMA-404? Never had a problem with JSON parsers or writers, using it all day every day for decades. It's crappy in some ways, sure, like lack of full floating point support, but standardization is not an issue.

XML is mostly already lost on the current generation of developers though, much less future developers. Protobuf and cousins generally do typed interchange more efficiently with less complexity.

WorldMaker
1 replies
4h24m

There are a lot of proponents that some or all of the "JSON5" [1] improvements should be standardized by ECMA as well. Especially because there is a mish-mash of support for such things in some but not all parsers. (Writers are a different matter.) Primarily comments and trailing commas, are huge wish list items and the biggest reasons for all of the other "many" variant parsers (JSONC, etc).

[1] https://json5.org/

int_19h
0 replies
3h10m

This is more of a concern for JSON configs and other such uses that are directly exposed to humans, but not really for machine-generated and machine-consumed data.

int_19h
0 replies
2h42m

It's focused almost entirely on syntax and ignores semantics. For example, for numbers, all it says is that they are base-10 decimal floating point, but says nothing about permissible ranges or precision. It does not tell you that, for example, passing 64-bit numbers in that manner is generally a bad idea because most parsers will treat them as IEEE doubles, so large values will lose precision. Ditto for any situation where you need the decimal fraction part to be precise (e.g. money).

RFC 8259 is marginally better in that it at least acknowledges these problems:

   This specification allows implementations to set limits on the range
   and precision of numbers accepted.  Since software that implements
   IEEE 754 binary64 (double precision) numbers [IEEE754] is generally
   available and widely used, good interoperability can be achieved by
   implementations that expect no more precision or range than these
   provide, in the sense that implementations will approximate JSON
   numbers within the expected precision.  A JSON number such as 1E400
   or 3.141592653589793238462643383279 may indicate potential
   interoperability problems, since it suggests that the software that
   created it expects receiving software to have greater capabilities
   for numeric magnitude and precision than is widely available.

   Note that when such software is used, numbers that are integers and
   are in the range [-(2**53)+1, (2**53)-1] are interoperable in the
   sense that implementations will agree exactly on their numeric
   values.
But note how this is still not actually guaranteeing anything. What it says is that implementations can set arbitrary limits on range and precision, and then points out that de facto this often means 64-bit floating point, so you should, at the very least, not assume anything better. But even if you only assume that, the spec doesn't promise interoperability.

In practice the only reliable way to handle any numbers in JSON is to use strings for them, because that way the parser will deliver them unchanged to the API client, which can then make informed (hopefully...) choices on how to parse them based on schema and other docs.

OTOH in XML without a schema everything is a string already, and in XML with a schema (which can be inline via xsi:type) you can describe valid numbers with considerable precision, e.g.: https://www.w3.org/TR/xmlschema-2/#decimal

bigstrat2003
0 replies
33m

Frankly, if a developer can't figure out XML then they aren't worth their salary. Age is no excuse here; as a developer your job involves figuring out how to work with technology you haven't used before.

jayd16
2 replies
3h33m

Its not JSON over XML. They're saying JSON REST won over _XML and SOAP_.

int_19h
1 replies
3h3m

Those two are kinda orthogonal, and while there was some overlap for adoption, it was fairly common to serve XML over REST early on (because more languages and frameworks had proven-quality XML parsers out of the box, so it was easier for the clients to handle).

JSON won in the end mostly because it was easier to handle in JS specifically, which is what mattered for the frontend. Then other languages caught up with their own implementations, although in some cases it took a while - e.g. for .NET you had to use third-party libraries until 2019.

neonsunset
0 replies
24m

To claim that pretty much every .NET project adding Newtonsoft.JSON as a first step was somehow a problem is just strange. No adequate team would claim this to be a problem.

Xarodon
0 replies
2h56m

XML parsers suffer the same fragmentation issues that JSON parsers do.

Go's XML parser straight-up emits broken XML when trying to output tags that have prefixed namespaces.

aaronbrethorst
2 replies
7h50m

Harder to get a promotion when you’re doing something that’s old, boring, and just works.

suzzer99
0 replies
4h13m

Especially if your job title has "architect" in it.

apantel
0 replies
3h58m

The closer you are to the cutting edge, the more sliced up you’re gonna get.

TheSoftwareGuy
1 replies
7h36m

I think us engineers have an inherent desire to try to innovate, and I think that is a good thing. Some problems will require a lot of wrong turns before finding the right path, but that is simply the nature of innovation

nurple
0 replies
6h51m

Agreed it's a good thing. Writing software today is still a slog that turns into a spaghetti bowl without focused intent by highly skilled devs. I think most devs realize this and really want there to be something better, and the only way to find something good is to find a lot of the bad around it first.

I like the thought experiment of adding a new persisted/editable field to an entity in a web app, if you've done full-stack you know all the layers that need to be touched to accomplish this and how lame most of the work turns out to be. After doing that 20 times while iterating, any dev worth their salt starts to wonder why it sucks so bad still and how it could be made better, and some will actually try.

solidasparagus
0 replies
1h45m

I think IDLs and gRPC in particular are a meaningful advancement in the problem space. The ecosystem and productivity that they enable via programatic tooling were really eye-opening for me (The OpenAPI ecosystem is, imo, extremely poor). They also have better support for modern techniques like streaming and even load-balanced streaming.

raxxorraxor
0 replies
6h58m

XML still has its usage and is excellent to quickly validate documents, but JSON clearly won in this use case because it was kept simple, stupid.

LeonenTheDK
0 replies
4h10m

and most likely a lot of the software we write will cease to be running in a decade

If only that were true in my experience.

DanielHB
58 replies
11h0m

GraphQL is very good for places where frontend and backend developers are isolated from each other (separate teams). Or rather places where you have data-producers and data-consumers as separate teams. If you have a big enough org eventually there will be many of such teams, interdisciplinary teams are not feasible at scale for everything.

It allows teams to work with less communication overhead. It solves more of a human problems than a technical problems, if someone think there is no value in that and bare metal performance is paramount that person never worked in a big org.

RPC and REST are just more straightforward to monitor, log, cache, authorize and debug.

In some ways yes, in others no. For example it can be near impossible to see if a deprecated field in a REST API is still being used and by which clients it is being used. With GraphQL this is fairly simple.

Unfortunately GraphQL way of working is very different from normal REST APIs and often requires more complex server-side caching. The N+1 problem needs to be figured out upfront for every data-storage system used in the backend.

BiteCode_dev
33 replies
9h49m

The problem is you delegate a lot of the query building to the client, hoping that it will not suddenly change your performance profile by being creative and that you will have not missed an obviously expensive use case coming.

That's a huge bet, especially given that GraphQL is expensive in the first place, and given that the more you grow the API in size, the less you can actually map the cartesian product of all request params.

strken
23 replies
9h11m

I'm not sure this is any more or less of a problem for REST APIs. What if your engineers change $client/$server and the new version makes really expensive queries? Well, ask them not to do that, then when some of them inevitably ignore you, start to review their code, terminate long-running queries, batch or pool fanouts so they don't take anything down, monitor new releases and roll back if anything breaks, etc.

If you're providing an external API like GitHub does, then that's a different story and I agree.

barrkel
9 replies
7h48m

If you have separation between front and back end, then the back end team can elect to serve REST APIs which only permit selecting, filtering, grouping and pagination that they know they can support within defined latency bounds for a given traffic level.

Thing get more problematic when there's vertical ownership for a feature, where the UI needs just a few extra things and you end up with a REST response which is fatter and fatter, in the interest of avoiding round trips and client-side joins.

The problem with killing correct queries that take too long is that it shows up as intermittent failure that's dependent on server load and data cardinality. You might not find it in testing and it ships a bad experience to the customer before bugs are found. Whereas APIs which can't be so easily misused make it much harder to ship bugs.

hansonkd
8 replies
7h22m

the back end team can select to serve REST APIs which only permit selecting, filtering, grouping and pagination that they know they can support within defined latency bounds for a given traffic level.

Why do you think that they can't do that with GraphQL? GraphQL isn't open ended. Its a highly restricted syntax for calling nested resources. If a resource is expensive simply don't nest it and make it a top level field and it is the same as REST?

Lots of nested resources are by default efficiently served by GraphQL because they are mostly returning single object foreign keys. Something that would take extra calls with REST.

GraphQL can have the same restrictions and performance guarantees as REST but the later is not necessarily true because in REST there is no standard way to define nested resource access.

clintonb11
7 replies
6h59m

I think the point here is, if you have to involve a backend team to add restrictions to the graphql endpoints and try to make good educated guesses where those might be, then the idea of frontend not needing backend engineers to query whatever they need becomes less of an advantage. So is the complexity of setting up graphql and then having your backend team try and make sure no frontend engineers can do terrible queries better for the software than custom rest APIs where needed and standard resource APIs everywhere else. Obviously it depends on the project. But I find the complexity of setting up and managing graphql often isn’t worth the pain, especially with schema first resource api designs and tooling like Google’s AIP linter.

hansonkd
6 replies
6h46m

if you have to involve a backend team to add restrictions to the graphql endpoints and try to make good educated guesses where those might be, then the idea of frontend not needing backend engineers

No because if you dont do that you have to involve more engineers anyways to build the REST endpoints and keep modifying the rest endpoints.

GraphQL is also default restrictive (i.e. exposes nothing). You don't need to add engineers to make it restrictive.

In Startups typically:

  -> Frontend changes most frequently
  -> Backend "utility functions " changes less
  -> Data model changes the least
Without Graphql your "backend" ends up needing to have a lot of work and changes because it is constantly needing to be updated to the needs of the most frequent changes happening on the frontend.

With GraphQL the only time you need to update the backend is when those "utility" functions change (i.e. 3rd party api calls, etc) or the data model changes.

So you end up needing substantially less backend engineers.

smaudet
4 replies
6h8m

With GraphQL the only time you need to update the backend is when those "utility" functions change (i.e. 3rd party api calls, etc) or the data model changes.

This is akin to saying that "directly exposing the database is easier, you only have to change things if the data changes".

And yes this is true, but when the data changes, or the environment changes, the paradigm falls apart a bit, no? Which is what the backend code was for, insulation from that.

In Startups typically:

Yes, so for a short lived, non-scaled application its far easier to do it one way, and maybe that's fine for most small apps (that will never scale far). I suspect a lot of the push back comes from larger, less nimble, more backwards-compat focused organizations/apps.

hansonkd
3 replies
5h58m

This is akin to saying that "directly exposing the database is easier

Far from it actually. I am saying that in practice the data and queries that you perform on your Database actually tend to stabilize and you add less and less as time goes on.

By Allowing the frontend to select what combination of these pre-approved queries that you already approved it can use, you have to do less and less backend work when compared to REST where you have to do backend work for every query combination you want to serve.

maybe that's fine for most small apps (that will never scale far).

I mean saying GQL doesn't scale for big apps is over looking one of the largest Corporate Software Orgs (FB) created and use it in production purposefully for managing large software APIs.

smaudet
2 replies
4h26m

By Allowing the frontend to select what combination of these pre-approved queries that you already approved it can use

Sure, so you are just filtering raw database access then. That doesn't make it any different - and, you still need to approve and filter these queries, so what exactly have you saved? I.e. either the front end engineers can change these filters, or not, so it amounts to the same thing in the case they can.

I mean saying GQL doesn't scale for big apps is over looking one of the largest Corporate Software Orgs (FB) created and use it in production purposefully for managing large software APIs.

That's not a great argument, though, saying a large company with many resources is capable of supporting something does not make it a sustainable technical decision. They likely also have a very specific work structure they use to make it for them.

In fact thats a strong reason not to use it, if it requires enterprise level resources to use it effectively. There is a big difference between technologies that scale to enterprise and technologies that require enterprise...

It still comes down to, if you can achieve 99% of the same thing with autogenerated REST apis and a couple page specific apis, what, exactly, is worth the considerable increase in complexity for that remaining 1%? Making things regularly more complex is a hallmark of failed, bad technologies, and I suspect GraphQL will see the dustbin like SOAP did...

hansonkd
1 replies
4h11m

You are bouncing back between it is ony for startups and it requires enterprise level maintenance. It can be used easily for both.

It still comes down to, if you can achieve 99% of the same thing with autogenerated REST apis and a couple page specific apis

Because you can get 100% by autogenerating GQL APIs and 0 page specific apis.

smaudet
0 replies
3h56m

You are bouncing back between it is ony for startups and it requires enterprise level maintenance. It can be used easily for both.

No, I never said that. You are the one that brought FB into the equation.

Just because it can be used for something does not mean that it should.

I said that that approach doesn't scale well, especially for frequent data/model changes. For small apps, where as you say, you have few data changes, by all means embed your database as closely as possible to you end user code.

Sqlite inside a c app or electron, e.g. No need for any API at all! Just raw query access.

Its nice GQL to generate stuff for small non-changing web apps, I'm sure. But once you get into more performance oriented, data-migration-style stuff, if there's not good support for changing the data and reacting to the environment, then adding complexity (GQL) to an already complex situation is a Bad Idea.

You never said what this 1% was, autogeneration is not a bonus when you already have to manually filter and route things. The simpler solution gets you there as well, with less fuss.

You think you don't have page specific apis, but if you are doing the manual filtering, then you still have them, you are just "hiding" them inside another language, that doesn't have a clear benefit? At least you can't say what it is, without going in circles, another sign GQL is probably ultimately a garbage technology...

BiteCode_dev
0 replies
5h24m

But you actually don't need to keep modifying the REST endpoints for most projects, that's what everybody is saying.

The vast majority of projects don't gain anything from this flexibility, because you don't have suddenly a 1000 of farmvilles copy cat that need their own little queries. You just have bob that need an order by.

jerf
7 replies
8h0m

There's a lot of relevant differences between REST & GraphQL. It is possible to construct a REST endpoint that simply can't do any of those things, and such construction is a mid-level developer task at best. For instance, pagination of "all posts ever" is not uncommon, and clients won't be shocked to deal with it. GraphQL is enough harder to characterize the performance of that it definitely qualifies as a change in quantity that is itself a change in quality. Hypothetically, both approaches are vulnerable to all the same issues, but GraphQL is far more vulnerable.

hansonkd
4 replies
7h0m

This is Wrong.

GraphQL only exposes what you ask it to. There are plenty of pagination plugins for GraphQL frameworks just as there are plugins to REST framework.

GraphQL can be restrictive as REST if you want it to be.

The point is GraphQL can be "as restrictive" as REST, but if you want to enable more efficient queries by knowing all the data that the frontend is requesting, you can. But the opposite isn't true of REST. With REST if you want more advanced functionality like that you have to define your own specification.

BiteCode_dev
3 replies
5h26m

But then what's the point of using it if it's to get the limitation of REST?

You get something more complex, more expensive to maintain, consuming more resources, and configure it to basically be REST with extra steps.

hansonkd
2 replies
5h20m

more complex, more expensive to maintain, consuming more resources,

Idk. Strawberry GQL and most GQL libraries are maybe equally as complex as the REST libraries for the same language. Strawberry and FastAPI I would say are equal in complexity and configuration.

It would be hard for me to say GQL is more expensive or consumes more resources. Opposite of the purpose and most uses of GQL.

BiteCode_dev
1 replies
4h31m

In stawberry you make a method per field you want to retrieve, I would say it is indeed more complex and costly.

hansonkd
0 replies
4h26m

What? Its a method per collection you want to return. or else it is a type annotation. Exactly as complex as FastAPI or any other typed system.

strken
1 replies
7h51m

Sorry, what? The original suggestion was that a developer would change things and it would cause performance problems. That same developer can change either a REST system or a GraphQL system and introduce the same performance issues in the same way, probably by adding a horrible N+1 query, or unbounded parallelism, or unbounded anything else.

Yeah, the client can't change the query if you don't let it specify a query, this is trivially true, but the developer can go break an API endpoint with the exact same result while trying to achieve the exact same business outcome.

jerf
0 replies
7h46m

The much more constrained input of the REST query means that the effect of changes on the API are much more comprehensible. Performance testing a particular REST endpoint is generally practical, and if a dev doesn't do it, the responsibility is reasonably placed on them. GraphQL means that you may do something you think is completely innocent like changing some index but for some query you didn't anticipate it trashes the performance. The range of things the dev of a GraphQL endpoint must be keeping track of is much larger than a REST endpoint, arguably exponentially so (though generally with a low power factor in practice, the possible queries are still exponentially complicated), and taking on any form of exponential responsibility is generally something that you should do only as a last resort, even if you do think your powers will stay low.

smaudet
2 replies
6h26m

What if your engineers change $client/$server and the new version makes really expensive queries?

Yes, so the cost benefit here is not in favor of GraphQL. If both technologies ultimately suffer from the same issues (what to do about unpredictable clients), but one is far more complex to implement and use (GraphQL), then there's a clear winner. Spoiler, its not GraphQL.

Page specific endpoints, I would argue, can do 99% of what GraphQL was trying to do. If you want to use it as some sort of template language for constructing page specific endpoints, that could be useful (the same way xml schema is useful for specifying complex xml documents).

But you can optimize a page specific endpoint, and do it with REST-style endpoint to boot.

Having a bunch of "simple" calls and optimizing for the "complex" ones that you need using metrics/analysis is what you should be doing, not creating a complex API that is far harder to break down into "simple" cases.

andrewingram
1 replies
3h9m

When you build a GraphQL server, you’re creating a system that outputs page-specific endpoints. They can be generated just-in-time (the default) or at build time (the general recommendation).

The engineering work involved shifts from building individual endpoints to building the endpoint factory. This shift may or may not be worth the trade off, but there are definite advantages, especially from the perspective of whomever is building the client. And once you factor in the ease at which you can introduce partial streaming with defer and streamable (granted they’re still WIP spec-wise), the experience can be pretty sublime.

smaudet
0 replies
2h0m

https://graphql.org/blog/2020-12-08-defer-stream/

This? Yeah, that seems neat, for command/batch queuing.

I'd be curious how it compares to e.g. rest apis returning refs to e.g. webrtc streams or tcp/udp ones for non-browser. I presume the main advantage would be client side.

sixdimensional
0 replies
7h0m

Even a SQL query can suffer the same fate. Ever tried writing a SQL query against a distributed database that isn’t optimized for that read path?

I think that’s what’s really pointing out the root cause issues here, it’s not purely GraphQL’s problem, it’s the problems inherent to distributed systems.

afavour
0 replies
8h9m

Obviously depends on the API but a REST API that maps relatively cleanly to database queries is going to make it very clear on both the client and the server when it’s not scaling well.

If, at page load, I’m making 100 HTTP requests to fetch 100 assets then as a client side developer I’m going to know that’s bad practise and that we really ought to have some kind of multi-get endpoint. With GraphQL that gets muddy, from the client side I’m not really sure if what I’m writing is going to be a massive performance drag or not.

tomrod
7 replies
9h33m

I haven't done much more than toy projects in GraphQL. Is there no way to limit the query complexity/cost? Such as a statement timeout in postgres?

chrisandchris
2 replies
9h18m

I'm not that much into GraphQL but I vaguely remember libraries that provide some kind of atteibutes you apply to entities/loaders and then pre-execution an estimated cost is calculated (and aborted if over a specified threshold).

tomrod
0 replies
9h11m

That's sort of my expectation too -- it would be nuts to provide a user facing system without bounds of some sort.

chuckadams
0 replies
5h31m

API Platform for PHP is one of those graphql implementations that has a query cost limiter built in (it's binary, it just rejects queries that go over your configured complexity threshold). Shopify's graphql api is even fancier, where every query costs X amount of a limited number of "credits". The structure of gql itself makes costs easier to estimate (you have as many joins as you have bracket pairs, more or less), and some servers can recognize a directive in the schema to declare the "real" cost.

BiteCode_dev
2 replies
9h29m

Ah but that's the beauty of GraphQL, a query can actually fetch data from several systems: the db, the cache, the search engine, etc. It's all abstracted away.

But let's say you have a timeout, and they have a retry, then suddenly, your server is now spammed by all the clients retry again and again a query that worked a week ago, but today is too heavy because of a tiny change nobody noticed.

And even if it's not the case, you can now break the client at any time because they decide to use a feature you gave them, but that you actually can't deal with right now.

barrkel
1 replies
7h46m

To be clear, the main thing that's abstracted away are server round-trips and client-side joins. REST APIs can fetch data from different systems too.

BiteCode_dev
0 replies
5h19m

Sure but queries are crafted in the client, that may know nothing about this, while a rest api, the requests are restricted and the queries are more likely under control of the server, which mean the backend will likely decide what fetches what and when.

It takes a lot of work to actually ensure all possible combinations of graphql params hit exactly what you want in the backend, and it's easy to mess with it in the frontend.

cmgbhm
0 replies
7h49m

There’s a free query depth. There’s ways to do query cost but federating that then becomes really annoying. Coming from the security side, there’s always a long curve of explaining and an even longer curve of mitigating.

I always am happy when I get an elegant query working. Often however I just find I wasted time looking for a clean 1 query solution when iteration by caller was the only solution.

tshaddox
0 replies
7h16m

When the client’s data requirements change, isn’t there always a risk that the data loading performance profile will change?

Surely that is always the case, if the client is composing multiple REST requests, or if there’s one RPC method per client page, or with any other conceivable data loading scheme.

dudeinjapan
21 replies
10h44m

Couldn't disagree more. GraphQL encourages tight-coupling--the Frontend is allowed to send any possible query to the Backend, and the Backend needs to accommodate all possible permutations indefinitely and with good performance. This leads to far more fingerpointing/inefficiency in the log run, despite whatever illusion of short-term expediency it creates.

It is far better for the Backend to provide Frontend a contract--can do it with OpenAPI/Swagger--here are the endpoints, here are the allowed parameters, here is the response you will get--and we will make sure this narrowly defined scope works 100% of the time!

RHSeeger
7 replies
9h56m

Can you explain what you mean by this? The GraphQL API you expose allows only a certain schema. Sure, callers can craft a request that is slow because it's asking for too much, but

- Each individual thing available in the request should be no less timely to handle than it would via any other api

- Combining too many things together in a single call isn't a failing of the GraphQL endpoint, it's a failing of the caller; the same way it would be if they made multiple REST calls

Do you have an example of a call to a GraphQL API that would be a problem, that wouldn't be using some other approach?

danielheath
5 replies
9h30m

The problem is that the client team can - without notice - change their query patterns in a way that creates excess load when deployed.

When you use the "REST" / JSON-over-HTTP pattern which was more common in 2010, changes in query patterns necessarily involve the backend team, which means they are aware of the change & have an opportunity to get ahead of any performance impact.

jerf
2 replies
7h55m

My blocker on ever using GraphQL is generally if you've got enough data to need GraphQL you're hitting a database of some kind... and I do not generally hand direct query access to any client, not even other projects within the same organization, because I've spent far too much time in my life debugging slow queries. If even the author of a system can be surprised by missing indices and other things that cause slow queries, both due to initial design and due to changes to how the database decides to do things as things scale up, how can I offload the responsibility of knowing what queries will and will not complete in a reasonable period of time to the client? They get the power to run anything they want and I get the responsibility of having to make sure it all performs and nobody on either side has a contract for what is what?

I've never gotten a good answer to that question, so I've never even considered GraphQL in such systems where it may have made sense.

I can see it in something big like Jira or GitHub to talk to itself, so the backend & frontend teams can use it to decouple a bit, and then if something goes wrong with the performance they can pick up the pieces together as still effectively one team. But if that crosses a team boundary the communication costs go much higher and I'd rather just go through the usual "let's add this to the API" discussions with a discrete ask rather than "the query we decided to run today is slow, but we may run anything else any time we feel like it and that has to be fast too".

foobarian
1 replies
7h31m

It seems there is a recent trend of using adapters that expose data stores over graphql automatically, which is kind of scary.

The graphql usage I'm used to works more or less the same as REST. You control the schema and the implementation, you control exactly how much data store access is allowed, etc. It's just like REST except the schema syntax is different.

The main advantage of GraphQL IMO is the nice introspection tools that frontend devs can use, i.e. GraphiQL and run queries from that UI. It's like going shopping in a nice supermarket.

ttfkam
0 replies
3h11m

Not particularly scary. For something like Hasura, resolvers are opt-in, not opt-out. So that should alleviate some of your concerns off the bat.

For Postgraphile, it leans more heavily on the database, which I prefer. Set up some row-level access policies along with table-level grant/revoke, and security tends to bubble up. There's no getting past a UI or middleware bug to get the data when the database itself is denying access to records. Pretty simple to unit test, and much more resistant to data leakage when the one-off automation script doesn't know the rules.

I also love that the table and column comments bubble up automatically as GraphiQL resolver documentation.

Agreed about the introspection tools. I can send a GraphiQL URL to most junior devs with little to no SQL experience, and they'll get data to their UI with less drama than with Swagger interfaces IMO. (Though Swagger tends to be pretty easy too compared to the bad old days.)

foobarian
1 replies
7h34m

changes in query patterns necessarily involve the backend team,

How does this follow? A client team can decide to e.g. put up a cross-sell shelf on a low-traffic page by calling a REST endpoint with tons of details and you have the same problem. I don't see the difference in any of these discussions, the only thing different is the schema syntax (graphql vs. openapi)

int_19h
0 replies
2h57m

GQL is far more flexible wrt what kind of queries it can do (and yes, it can be constrained, but this flexibility is the whole point). Which means that turning a cheap query into an expensive one accidentally is very easy.

A hand-coded REST endpoint will give you a bunch of predefined options for filtering, sorting etc, and the dev who implements it will generally assume that all of those can be used, and write the backing query (and create indices) accordingly.

serpix
0 replies
9h32m

Then we just come back full round trip to REST where the backend clearly defines what is allowed and what is returned. So using GraphQL it is unnecessary complicated to safeguard against a caller querying for all of the data and then some. For example the caller queries nested structures ad infinitum possibly even triggering a recursive loop that wakes up somebody at 3am.

DanielHB
6 replies
9h17m

It is far better for the Backend to provide Frontend a contract

It sure is better for the backend team, but the client teams will need to have countless meetings begging to establish/change a contract and always being told it will come in the next sprint (or the one after, or in Q3).

This leads to far more fingerpointing/inefficiency in the log run, despite whatever illusion of short-term expediency it creates.

It is true it can cause these kind of problems, but they take far, far, far less time than mundane contract agreement conversations. Although having catastrophic failures is usually pretty dire when they do happen, but there are a lot of ways of mitigating as well like good monitoring and staggered deployments.

It is a tradeoff to be sure, there is no silver bullet.

jpalawaga
4 replies
8h3m

trying to solve org problems with tech just creates more problems, allthewhile not actually solving the original problem.

smaudet
1 replies
6h18m

Yup. And the solution to that org problem is for the front engineers to slow down, and help out the "backend" engineers. The complexity issues faced by the back-end are only getting worse with time, the proper solution is not adding more complexity to the situation, but paying down the technical debt in your organization.

If your front-end engineers end up twiddling their thumbs (no bugs/hotfixes), perhaps there is time (and manpower) to try to design and build a "new" system that can cater to the new(er) needs.

DanielHB
0 replies
5h32m

GraphQL is the quintessential move fast and break things technology, I have worked in orgs and know other people who have done so in other orgs where getting time from other teams is really painful. It is usually caused by extreme pressure to deliver things.

What ends up happening is the clients doing work arounds to backend problems which creates even more technical debt

clintonb11
1 replies
6h54m

This is what I wanted to say too. If your backend team is incapable of rapidly adding new endpoints for you, they probably are going to create a crappy graphql experience and not solve those problems either. So many frontend engineers on here saying that graphql solves the problem they had with backend engineers not being responsive or slow, but that is an org problem, not a technology problem.

dudeinjapan
0 replies
6h26m

At TableCheck, our frontend engineers started raising backend PRs for simple API stuff. If you use a framework like Rails, once you have the initial API structure sketched out, 80% of enhancements can be done by backend novices.

finack
0 replies
5h55m

I never understood why this was such a big deal... "Hey, we need an endpoint to fetch a list of widgets so we can display them." "Okay." Is that so difficult? Maybe the real problem lies in poor planning and poor communication.

fire_lake
2 replies
7h56m

A GraphQL schema is a contract though.

And the REST API can still get hammered by the client - they could do an N + 1 query on their side. With GraphQL at least you can optimize this without adding a new endpoint.

dudeinjapan
1 replies
6h24m

Yes, GraphQL is a "contract" in the sense that a blank check is also a "contract".

arcticfox
0 replies
6h9m

You can whitelist queries in most systems though. In development mode allow them to run whatever query, and then lock it in to the whitelist for production. If that type of control is necessary.

gedy
0 replies
7h59m

the Frontend is allowed to send any possible query to the Backend

It's really not, it's not exposing your whole DB or allowing random SQL queries.

It is far better for the Backend to provide the Frontend a contract

GraphQL does this - it's just called the GraphQL "schema". It's not your entire database schema.

chuckadams
0 replies
5h22m

Most REST APIs I've seen in the wild just send the entire object back by default because they have no idea which fields the client needs. Most decent REST API implementations do support a field selection syntax in the query string, but it's rare that they'll generate properly typed clients for it. And of course OpenAPI has no concept of field selection, so it won't help you there either.

With my single WordPress project I found that WP GraphQL ran circles around the built-in WP REST API because it didn't try to pull in the dozens of extra custom fields that I didn't need. Not like it's hard to outdo anything built-in to WP tho...

beeboobaa3
0 replies
10h34m

Not to mention the fact that GraphQL allows anyone messing with your API to also execute any query they want. Then you start getting into query whitelisting which adds a lot of complexity.

tuan
0 replies
8h9m

GraphQL is very good for places where frontend and backend developers are isolated from each other (separate teams)

What do you mean by "backend developer" ? The one who creates the GraphQL endpoints for UI to consume ?

afiori
0 replies
10h34m

In some ways yes, in others no. For example it can be near impossible to see if a deprecated field in a REST API is still being used and by which clients it is being used. With GraphQL this is fairly simple.

You should log deprecation warnings.

But also if the client is composing urls/params manually then you are not doing REST, you are doing RPC.

Rest APIs should mainly use HATEOAS hyperlinks to obtain a resource. that is clients almost always call links you have provided in other reponses (starting from a main entrypoint)

hinkley
1 replies
5h2m

I knew we were in trouble when we started having to sort the query criteria in order to support caching of requests.

If I use graphQL again it’ll only be for admin features. Anything where very few users will use it and very infrequently. Preferably in spots where caching works against the workflow. OLAP vs OLTP.

GraphQL is really about reducing friction between teams. High functioning distributed systems all have two qualities in common: work stealing and back pressure. Without back pressure there is nothing to stop the project from running off a cliff.

esafak
0 replies
1h14m

what's work stealing?

bryanrasmussen
1 replies
5h20m

And both these projects had clear signs of "learning-on-the-go" with loads of bad practices

I think two projects having loads of bad practices is too small a dataset to really assume anything, you sort of need to see widespread "bad practices" in the tech to be able to determine that the bad practice is actually the norm practice and there is perhaps a flaw in the tech that encourages that norm.

arp242
0 replies
4h42m

You're not wrong, but at the same time I think it's a decent data point that getting it right is not straight-forward and that, practical speaking, you at the very least need to think very carefully before actually using it.

"The idea of it" is sometimes fine, but then there's also "the practicality of it", and sometimes that's a very different thing.

Remember the old microkernel vs. monolithic debate; everyone more or less agrees that in principle, a microkernel is better. But the practicality of it is a lot more complex, so monolithic kernels and hybrid ones are much more common. Microservices vs monolithic is essentially the same debate, and I've seen a lot of Microservices with very poor implementations and a lot of problems. That doesn't mean the idea is bad in itself, but if it's hard to execute well, then you do need to be very careful.

There's tons more examples of this. You also see this sort of thing in e.g. politics, where what's "more fair" vs. "what's actually achievable without introducing heaps of bureaucracy and overhead" are sometimes very different things.

In the case of GraphQL, I think it's pretty obvious that the general idea, as described from a high level, is a good one. But the practicalities of it are a lot less straight-forward, as this article explains reasonably well IMHO.

taeric
0 replies
4h51m

That fun fact bothers me at a fundamental level. I've seen it happen so many times and is really painful when the people were promoted out of the place. Even worse when they are good developers, but often in a cowboy style where they confuse their energy for some fundamental efficiency of what they were doing.

pavel_lishin
0 replies
9h29m

We have similar issues in our codebases - but not just in GraphQL, but also in our PHP and Elixir code, and to some extent our Typescript stuff.

I think the "learning-on-the-go" symptom, where you can sometimes literally read down a file and watch some developer learn the language as they add more and more functions to the file with a gradual increase in skill (or, to put it less charitably, as they slowly get less bad at writing code) is probably a very common thing, and not just a GraphQL issue.

flashgordon
0 replies
6h49m

> Fun fact; in both these projects the original devs who set it up were no longer involved. Probably spreading their evangalism further elsewhere.

Ah this brings up bitter memories. Team I was managing was roped in to become the first graphql framework (nay platform) the ivory tower (central architecture run by the cto) team was building and trying to shove down the rest of the company. This was during the graphql craze around 5 years ago. The principal engineer leading it was even preemptively promoted to distinguished engineer for future contributions.

Fast-forward 5 years project was disbanded due to massive migration, cost and complexity problems. DE still lauded for experimentation heroism and evangelism. I think he is now pushing the latest flavors of the month to go for the next promo!

canadiantim
0 replies
6h1m

Now where does Braid-HTTP fit in?!

joshstrange
29 replies
4h34m

I bought into the hype and I feel bad for the company where I implemented it. One true endpoint to rule them all and cause endless headaches in the process.

With most tech that I screw up I assume that "I wasn't using it right" but with GraphQL I'm not sure how anyone could. The permissions/auth aspect alone is a nightmare. Couple that with potential performance issues (N+1 or just massive amounts of data) and I want nothing to do with GraphQL anymore. Everything we attempted to fix our permissions issues just caused more problems. It would break existing queries and debugging GraphQL sucked so much.

If you only live on the frontend and someone else is responsible for the backend GraphQL then I understand why you might like it. From that perspective it's amazing, you can get as little or as much as you want with the specific fields you want. No waiting on the backend team to write an endpoint. However even then you end up saving queries as files or abstracting them (maybe IDE support has improved but it wasn't great last time I was using it ~5 years ago) and now you just have REST endpoints by another name.

At one point we considered whitelisting specific queries and that's when I knew we had gone too far and made a mess for ourselves. If we had taken the time to just write REST endpoints instead we would have gotten way more done and had way fewer grey hairs.

hosh
6 replies
4h16m

Hmm. I wonder if there is some kind of query builder that can live server-side. That is, capture the flexibility of a query language when developing, and then consolidating that when going into production.

Though I guess you can do that with REST too.

I'm currently exploring all of this myself. I have a side project in mind that can use a graph db, and I thought a front-end graphql can work well with a graphdb backend. I was not sure why this pattern is not more popular, but reading all of this now, I'm seeing where these problems may arise.

A graph db backend can use efficient graph search algorithms, especially for deeply nested data, but the issue with authorization is still there. If anything, fine-grained authorization is something better represented with graph dbs than with relational databases.

AaronFriel
2 replies
3h37m

This is a vague recollection, but I seem to recall Meta/Facebook engineers on HN having said they have a tool that allows engineers to author SQL or ORM-like queries on the frontend and close to where the data is used, but a compiler or post-processor turns that into an endpoint. The bundled frontend code is never given an open-ended SQL or GraphQL interface.

And perhaps not coincidentally, React introduced "server actions" as a mechanism that is very similar to that. Engineers can author what looks, ostensibly, like frontend code, merely splitting the "client" side and "server" side into separate annotated functions, and the React bundler splits those into client code, a server API handler, and transforms the client function call into the annotated server function into an HTTP API call.

Having used it for a bit it's really nice, and it doesn't result in yielding so much control to a very complex technology stack (GraphQL batchers, resolvers, etc. etc.)

svieira
1 replies
2h15m

I seem to recall Meta/Facebook engineers on HN having said they have a tool that allows engineers to author SQL or ORM-like queries on the frontend and close to where the data is used, but a compiler or post-processor turns that into an endpoint.

I don't know about on-HackerNews but there's a discussion about their "all of Facebook optimizing compiler" infrastructure from when they did the site redesign in 2020: https://engineering.fb.com/2020/05/08/web/facebook-redesign/...

perhaps not coincidentally, React introduced "server actions" as a mechanism that is very similar to [the above]

Yep - there's also the Scala framework LiftWeb (https://www.liftweb.net/), the Elixir framework Phoenix (https://www.phoenixframework.org/) and of course the system we're using right now (Arc) that do similar things. Scaling these kinds of UUID-addressed-closures is harder (because the client sessions have to be sticky unless you can serialize closures and send them across the network between servers).

jamra
0 replies
1h41m

Code generation is very common at Meta. One just needs to create a query or fragment. A fragment can be spread at the root query level using relay so it will do the fetch once. It gets more complex because you can lazily query more data based on parameters you pass into GQL. It feels like magic and is really annoying imo.

nkozyra
0 replies
4h0m

Hmm. I wonder if there is some kind of query builder that can live server-side. That is, capture the flexibility of a query language when developing, and then consolidating that when going into production.

I think this is what a lot of people end up doing (and yes, with REST). Translating options via query params / POST body into a query. In theory GraphQL was supposed to mitigate this DSL-like translation, but the thing is people like flexibility and ability to change and, yes, break backwards compatibility. That's also why a lot of people end up with a translation layer with things like RPC, which is itself supposed to be a direct, shared communication protocol.

The messiness of APIs is often a feature, at least internally. These approaches that attempt to avoid the mess are better for the end consumer but cause friction within development groups and the benefits are often obscured.

andreimackenzie
0 replies
2h22m

Assuming the query language for the graph DB you have in mind is declarative like SQL, I recommend templated queries. I have found this technique scales pretty well for query complexity, makes it relatively trivial to "get to the query" if something needs to be debugged in the details more easily outside of the app, and it makes performance-oriented optimization work far easier.

I've had my share of headaches with the various flavors of ORM and GraphQL and always come back to query templates, e.g. MyBatis in the JVM ecosystem or Go's template package. There is still value in abstracting this from the REST web service interface to make it possible to change the app<->database connection without disrupting REST clients. It's possible to reuse parameter structs/classes between the REST client and DB+template client layers to avoid a lot of rote translation. It seems simple and repetitive, but actually saves time compared to the GraphQL/ORM complexity as apps & query complexity scale, in my experience.

awongh
4 replies
2h5m

I’ve only been a consumer of a GraphQL API, so I don’t know what it’s like to maintain, but I mostly enjoyed using it.

Of course the documentation on some kinds of query syntax was too sparse, (this is for Shopify) but I could see how it might be nice for certain kinds of cases. If you run a platform it might be a good option to offer in your API. For shopify afaik there are equivalent calls in both REST and graphql so you have options.

pas
2 replies
1h31m

Can you elaborate on lack of syntax docs? As far as I understand one of the big big huugge benefits of GraphQL is that you get the strongly typed schema via the introspection query, so you can build queries with some confidence, that as long as the schema (version) is the same it should be syntactically okay. What did Spotify do compared to this?

awongh
0 replies
18m

I think it wasn't just the schema structure, it was the API abstractions implemented in the schema.

If I remember correctly it was something about Shopify discounts, which can be applied multiple times and across different modalities- percent, dollar amount, etc. and what those were called in the API, and how they were represented and to which object they were applied to.

Then once I had figured that out, then understanding how to construct the query.

But of course my problem was more from the point of view of, "I just want to get x done". As the consumer of the API I wasn't as concerned about fully understanding the entire set of abstractions and schemas.

albertgoeswoof
0 replies
53m

This is one of the problems with graphql, there are no docs because the schema is all you need. But that assumes the schema is logical and consistent, which it rarely is.

It also means you need to be an expert in the tooling to figure it out, so just dropping in to a graphql api is so frustrating compared to plain old rest

vdfs
0 replies
57m

equivalent calls in both REST and graphql so you have options.

It's not that simple, new features are add to GraphQL only, some other things are REST only,some APIs work differently (like product search by title, in REST it have to be an exact match, in GQL it can be partial match)

teaearlgraycold
3 replies
3h4m

I think a lot of people like GraphQL because it provides strongly typed API interfaces. But I've been able to hack together a better REST alternative in full-stack typescript codebases. And my solution doesn't need to compile any kind of client or intermediary.

rbalicki
1 replies
31m

GraphQL gives you the ability to compose fragments, so if the UserDetail component and UserPaymentInfo component both use the user’s name, it is loaded once.

With ad hoc solutions like tRPC, you end up fetching the same field multiple times (and probably doing some sort of network waterfall), or you give up on data masking and composability. And if you have enough engineers, data masking and composability are critical to maintain velocity.

teaearlgraycold
0 replies
21m

swr can handle the first issue you mentioned just fine.

burutthrow1234
3 replies
4h14m

GraphQL absolutely feels like a technological solution to an organizational problem. What if your front-end team wants to write crazy queries and your back-end team wants to build their resume doing Real Engineering, but what you actually need is just a CRUD app?

Now your backend devs aren't bored writing "business logic" and your front end devs aren't bored waiting for your backend devs. You have a new class of inscrutable errors and performance issues, but that's why you pay your backend devs the big bucks! Because some guys from a technical college couldn't possibly solve your issue, you need to pay 250k to people who went to Stanford or Berkeley.

sodapopcan
0 replies
1h59m

This was my experience. We were forced to use it in a project where we controlled the entire stack. It was so much extract work just to serve data from a backend we had full control over. I don't dislike it but I feel like it's far more of a time-and-place technology than most that people just default to using in any old situation. I'm sure some have used it successfully in a similar scenario—we certainly weren't exactly super knowledgable about it when we were told to use it. We tried, though!

jack_riminton
0 replies
3h33m

Yep, Conway’s Law:

“ Any organization that designs a system will inevitably produce a design that mirrors the organization's communication structure. “

Your point about Resumé Driven Development, together with the dividing wall between front and backends is why FE frameworks have got so hideously and needlessly complex imo

ForHackernews
0 replies
2h8m

Sounds good to me. I'll do GraphQL for $250k.

nfw2
2 replies
3h9m

Whitelisting the queries that clients can use in prod actually doesn't seem like a bad option to avoid a lot of these security issues, assuming you control the clients

rbalicki
0 replies
34m

This solution works very well, and I’m surprised that others on this thread do not take advantage of persisted queries. Yes, it’s recreating REST, except that you don’t need to version endpoints, etc. The source of truth is the front end repo. That’s the point!

Use of persisted queries also addresses the article’s concerns about DDOS.

joegibbs
0 replies
54m

Yeah but then you’ve basically just remade REST, but the queries are stored in the frontend instead.

pyr0hu
1 replies
1h48m

Can you give an example for the permission issues that you had with GQL and would've been easier in REST? Genuinely curious, as I'm implementing a GQL backend with simple permission handling and haven't run into anything yet, but I wanna know what could await me

joshstrange
0 replies
1h32m

With REST I can fairly easily filter out any data based on roles/permissions either at query time or before turning it into JSON. With GraphQL I need that info deep in the resolver logic and for nested data I don't want to fetch the name of a person if they calling user doesn't even have access to see that user (and I don't want to fetch the user and their name only to delete it from the response later). GraphQL, being so open-ended to what you are fetching, means I have to make sure to plug a ton of holes whereas REST I have a specific query, there is no way to fetch nested data (unless I specifically allow it via GET/POST params). I can easily say "If role X -> use this query, if role Y -> use this query, etc", I found that very difficult to do in GraphQL.

GraphQL feels like magic when you first start with it (which should be a red flag) but once you need to support more roles or sets of permissions and as your business logic starts to creep in things go haywire. In my experience things that are easy up front are unmanageable once business logic gets added in. For straight CRUD it's amazing but very rarely do our apps stay as just CRUD and that's when things fall down. For example, on create of a new user I need to send a welcome email. It's been 5 years since I was working on that GraphQL project but I have no clue how we'd handle that. I'm sure there is some kind of a event system we could hook into but with REST I just have a simple endpoint that saves the data to the DB and then sends and email (or puts it in a queue), way easier than in GraphQL. Again, fetching and updating data is easy until you need to handle edge cases. I have the same feelings about Firebase and friends. Feels like magic at the start but falls down quick and/or becomes way too complicated. GraphQL feels like DRY run amuck, "I have to keep writing CRUD, let me abstract that away", ok but now if you need special logic for certain use-cases you have a mess on your hands. Maybe GraphQL has ways to solve it but I'll bet my hat that it's overly complicated and hard to follow, like most of GraphQL once you get past the surface.

I'd love to see a "Pet Store" (I think that's the common example I've seen demo'd in REST/Swagger/GraphQL/etc) example with heavy restrictions based on different users/roles. It's like using the "Todo app" example in a framework, sure that works and is straight forward, I want to see how you handle the hard stuff and if it's still easy.

lcnmrn
1 replies
3h33m

Someone like you made me quit my first job as developer. He implemented a Clojure + GraphQL nightmare.

joshstrange
0 replies
1h30m

Well that wasn't me, I implemented an Akka + GraphQL nightmare instead :)

Joking aside, I'm sorry that happened to you and I'm sorry for the people that took over the system I helped to write.

mattacular
0 replies
1h33m

I had an eerily similar experience with GraphQL where by the end of "productionizing" the backend to support the client load, were using whatever their equivalent of cached/persisted queries is called (sorry I can't recall their terms for this). We had ultimately come full circle to something that was harder to use than a REST API but also more complicated at every layer.

giantg2
0 replies
4h2m

My biggest problem is that it seems like nobody understands the data or where the data is coming from. You can have the same variable names and mostly even the same values under different levels of the graph. Now someone has to figure out what system is feeding that info to GraphQl to figure out which level we should use. I don't see this as a real GraphQl problem, but more so a problem with the process discouraging detailed knowledge and documentation.

lpapez
26 replies
11h30m

Kudos to the author for reevaluating his opinion and changing heart on a technology he admits to have championed before.

IMO GraphQL is a technological dead end in much the same way as Mongo is.

They were both conceived to solve a perceived problem with tools widely adopted at the time, but ended up with something which is even worse, while the tools they were trying to replace rapidly matured and improved.

Today OpenAPI REST and Postgres are rightfully considered as the defaults, you even have PostgREST combining them, while most of those who adopted Mongo or GraphQL have either long migrated or are stuck discussing migrations.

FrustratedMonky
7 replies
11h12m

Curious, I hadn't heard that take on Mongo. Do you have a link to some more info on this.

FrustratedMonky
3 replies
10h20m

That is pretty funny, But that video is 11 years old. It can't still be like that? can it? Seems like people are down on Mongo in the last year, and I'm trying to catch up.

mst
2 replies
9h35m

WiredTiger was kinda Mongo's InnoDB and has made "your data will actually still be there later" rather more true than it used to be.

I think the key thing is that people using MySQL were having trouble with deep data and found MongoDB's document oriented approach much easier, but these days people are tending to start with PostgreSQL, which can handle that nicely.

(MySQL/MariaDB are far better than they used to be as well, though I find most stuff I read online doesn't take advantage of that as much as it might)

There's also probably a factor of Mongo solving pain points people had when they switched to it, and there being lots of excitement around that, where today the same people have run into the pain points of Mongo often enough that it's no longer nearly so exciting a prospect.

I wouldn't honestly be surprised if we're now at a point where people are -more- negative about Mongo than it really deserves, and I say that as somebody who viscerally hated it on sight and would still rather avoid dealing with it myself it if at all possible.

(oh and MongoDB the -company- has always done their best to be a good corporate community citizen, sponsoring all sorts of cool things as a result, and while I think the license change was a shame I -still- think they're doing their best, just in an environment where they wouldn't have a best to try to do in the first place if they didn't avoid being killed by AWS)

darthmallrat
1 replies
7h30m

the license change was a shame ... avoid being killed by AWS

That sounds similar to Elastic's story. Did MongoDB go through that as well?

rglover
0 replies
2h57m

It's a shame that this out of date/meme stuff continues to give MongoDB a bad rap. It's a great DB if you need to be flexible/move fast and avoid migration headaches (speaking first hand, this has dragged dev cycles quite a bit). Most startups/saas/web apps would benefit greatly from using MongoDB purely from a reduction of complexity standpoint.

The current version of MongoDB, imo, makes you super productive and scales without a ton of thinking. If you're working in Node.js, it's even more useful as the query language works just like a JS/JSON object so writing queries is super fast (compared to SQL where you have to spend a lot of mental cycles figuring out how to map object/array data).

I've found that denormalizing data (not even necessarily copying/duping data, but trying to centralize storage of it) when using MongoDB is the way to get the most value out of it. If you try to treat it like an RDB (which does work but can cause issues with complex queries), you'll run into headaches. If you just design stuff to be nested, though (and use the built-in APIs to query that nested data), it works incredibly well.

lpapez
0 replies
10h37m

I have not saved any links to back this up.

It is just my personal observation formed from working with Mongo and migrating systems away from it.

hot_gril
5 replies
5h16m

People need to stop judging the viability of something based on how satisfying it feels to use it in a toy project. When time is money, you'll see what really works.

At least GraphQL supposedly works for Facebook, and I tried it out before deciding it wasn't a default. I never even bothered with MongoDB. I've had to repeatedly veto using both in projects, cause someone thought it'd be cool and thought that was a good enough reason. Finally it's not cool anymore, but there will be another thing.

asdasdsddd
4 replies
5h7m

GraphQL works when you have an army of engineers that are able to solve all the perf issues

suzzer99
2 replies
4h2m

Everything works when you have an army of top-flight engineers.

hot_gril
1 replies
4h1m

I can name plenty of engineering tasks an army of top engineers has failed at, to the point of negatively impacting the product.

suzzer99
0 replies
3h52m

Ok, "most things". ;)

hot_gril
0 replies
5h2m

Maybe. Can that one army fix GraphQL for all the teams in the company? Cause I've seen things work that way, but I've also seen tools that are pitched as "maintained in one place for everyone" but are actually a complexity burden on every single team, especially if/when its usage changes.

foobarian
3 replies
7h25m

IMO GraphQL is a technological dead end in much the same way as Mongo is.

Can you suggest alternatives to graph introspection and related UI tools like GraphiQL, and the subgraph federation systems?

petesergeant
0 replies
6h35m

What are the use-cases for graph introspection in any but a tiny fraction of cases?

eYrKEC2
0 replies
6h14m

It may not be an exact analog, but "swagger UI" for openapi is the best I've seen like GraphiQL. Example https://petstore.swagger.io/ . Not sure of other alternatives.

No analog for "subgraph federation systems", unless a load balancer will suffice.

aobdev
0 replies
6h20m

OpenAPI has a handful of open source API explorers. The ones I’m familiar with are Swagger UI, Redoc, and RapiDoc.

OpenAPI 3.0 has this concept of remote references, which can be URLs to other OpenAPI specs hosted anywhere. https://swagger.io/docs/specification/using-ref/

otabdeveloper4
1 replies
10h11m

Mongo is great if you want a distributed replicated log. Existing tools sorely lack. (Postgres and Kafka are broken by design.)

FridgeSeal
0 replies
8h59m

Curious as to why you think Kafka is broken by design?

culi
1 replies
2h37m

Just a couple nitpicks

* openapi was basically nonexistent when GQL came out. It certainly wasn't "the tool they were trying to replace"

* Postgres and GQL are not in any way mutually exclusive

* Today, openapi is still tiny compared to GQL. At least as measured by StackOverflow question tags:

https://trends.stackoverflow.co/?tags=graphql,openapi,soap,m...

koito17
0 replies
46m

Stack Overflow trends isn't really a good metric, but setting that aside, you need to sum the time series for Swagger and OpenAPI. There's still plenty of people who call OpenAPI 3.0 "Swagger". And strictly speaking, Swagger is "OpenAPI 2.0".

chrisdrobison
1 replies
2h2m

No idea why you bundle Mongo in there. I use Mongo in multiple production apps and I've never, ever looked back. Wouldn't even consider RDBMS's at all after my experience with Mongo unless I absolutely had to.

Culonavirus
0 replies
1h36m

What kind of "production apps"? A todo list saas?

I swear, the older I am, the more convinced I am that people who don't use a RDBMS just don't work on complex systems. Period.

CuriouslyC
1 replies
10h29m

GraphQL by itself has a lot of issues, but Hasura is IMO a power tool. It gives you CRUD with a security model and a lot of bells and whistles out of the box, and paired with Apollo client on the front end it's pretty quick to set up and use. I still use random REST endpoints, and I'm not interested in federation, but as a quick way to get an app going it's great.

dventimi
0 replies
8h32m

Same, with a shout out to PostGraphile as well. As an aside, I'm sorry but I roll my eyes every time I encounter data loaders and the N+1 problem it's meant to address but which really is a consequence of insistence on following the resolver execution model. GraphQL is a query language. Just compile it to SQL (or Cypher, or SPARQL, or whatever)...when that's possible.

0-bad-secrotrs
23 replies
10h29m

Aside from all the valid points listed in the blog I found out that the frontend engineers in my company save some queries in central library and reuse them even if they don't need all the field returned by this array just to save themselves the time they spend writing queries so they are basically using GraphQL as REST at the end and now we have the worst of both worlds.

brabel
13 replies
10h12m

Our frontend team needs to show the whole thing every time (as the user sees and edits full resources in most cases), which means they MUST keep a full query representing the entire resource, and when we add stuff in the backend, they must also add those things in the frontend (as they cannot generate UI for new things in most occasions). GraphQL was really a mistake for us.

RedShift1
12 replies
10h10m

Why is this a problem? If you add fields on a REST endpoint, you're going to have to change the client too to deal with those new fields.

chasd00
8 replies
8h8m

If new fields show up in a json response just ignore them. Why would you need to change the client if new fields show up in the response?

wruza
3 replies
6h21m

Because receiving unexpected data is a signal you rarely want to ignore in programming. Doesn’t matter whether you’re gonna use it or not.

finack
1 replies
5h53m

No, that's an important facet of compatibility. If a change is purely additive, existing clients will keep working, something the industry has basically forgotten all about, it seems.

wruza
0 replies
2h4m

I think I have to agree with this correction in general, but don’t take one commenter for a whole industry please. I’m not even remotely representative of it.

int_19h
0 replies
2h54m

In OOP, the equivalent - getting an object of some more specific type than the one you asked for at API level - happens all the time.

tossandthrow
3 replies
6h35m

Indeed, this is what graphQL solves.

Are you proposing just to add new field to a JSON response, even though they are not needed?

eatsyourtacos
1 replies
5h38m

Are you proposing just to add new field to a JSON response, even though they are not needed?

That is exactly what OP is proposing and it makes total sense. More data != bad. Just ignore if you don't need it. For 99.999% of cases the bandwidth of extra data is entirely negligible.

For business cases you just want to get things done. If the server has added more data, which is obviously relevant in some regard, you can see it and might want to use it etc. With GraphQL you are completely stuck without SPECIFICALLY requesting it. That means every client needs to know about the new data and specifically request it. In theory that might sound like it makes sense, but in practice this is virtually never the case.

Give me all the data and I'll use what makes sense.

tossandthrow
0 replies
2h9m

What decides what data to include?

Or are you just sending all data the client cloud possibly see over?

scubbo
0 replies
5h34m

GraphQL "solves" the ability to ignore an unneeded field in a response? Revolutionary.

nevir
0 replies
5h36m

One problem is performance.

(Most) GraphQL clients are optimized for relatively small/simple objects being returned, and you typically pay a cost for every single edge (not node) returned in a response / cached in memory.

It can quickly get to the point where your project is spending more time per frame processing GraphQL responses & looking data up from the cache than you spend rendering your UI

em-bee
0 replies
9h7m

depends. i'd be writing the client such that it just lists all the fields, and then add special handling for the fields that need it. when the backend adds new fields, they will just show up and i just need to fix the formatting. with graphql i'd have to ask for those new fields, and thus make changes in two places. and in addition the backend team has to tell the frontend team about the new fields (instead of letting the api speak for itself), making it easier to accidentally skip a field.

culi
0 replies
3h10m

it sounds like they are just dumping every field to somehow show the user without any validation/specific rendering logic for each field

culi
2 replies
3h12m

This isn't actually that terrible since these fields are cached by a client-side library like Apollo. If the query has already been made elsewhere then it won't be doing any extra work

The only downside is if one of those unused fields changes due to a mutation then all components using that field will rerender (ofc I'm assuming React here). Again, not the biggest concern if you've got your memoization set up correctly

4hg4ufxhy
1 replies
1h29m

You missed the actual downside of this only works if there is no mutations in the background from other clients/processes making your cache stale.

culi
0 replies
5m

you can poll or subscribe within GQL. The same solutions you'd use with a rest-based api

hombre_fatal
1 replies
8h44m

The difference is that the client came up with its own data access patterns instead of having to rely on the server to design the exact endpoints that it needs.

Overfetching or not, that's a rather big difference.

eatsyourtacos
0 replies
5h44m

Sure, but just how often is the client the one who defines what data it needs without the designer being able to create obvious endpoints?

Surely there are some good use cases.. just so few and far between. No one should be using GraphQL unless absolutely necessary.

tarentel
0 replies
5h36m

We do something similar and it's because GQL at my company is really pointless. I think someone at some point someone also got on the hype train not realizing that we do not really need to have hyper specific queries we can write on the fly. I can't think of a single instance where someone proposed a feature and we all went well, we can combine these 3 things we already have into a new query and the backend has no work to do. The backend always ends up building out more into graph and have been doing so for at least 6 years now. There have been a handful of cases where we did combine something old with something new but given the extra complexity on the client and backend I'm not sure it was worth it over making 2 separate calls.

squidsoup
0 replies
1h57m

This is easily fixed by introducing a linter - relay complains about unused fields by default.

amjnsx
0 replies
6h19m

Sounds like an issue with your team rather than graphql

015a
0 replies
7h27m

Yup, we saw the same thing. Everyone wants RPC. That's it. We keep inventing crazy complicated patterns on top of RPC that serve mostly as good fodder to yell about in meetings, when `POST /list_users` and `POST /create_user` work great.

dzonga
18 replies
9h56m

when will people learn - you're not Facebook, or will never likely reach facebook scale. Graphql, Relay, React were things etc made for Facebook at facebook scale i.e whether that's in terms of engineers, resources or actual tech problems.

There's plenty of other sites / services that receive almost as close to FB properties in terms of traffic yet you never hear them pushing all those tools. Trading firms, Porn firms etc. Some just use REST + JSON or RPC + JSON.

Wish us an industry would read Joel's Spolsky's Fire and Motion article: While you're fighting tools built by FB you're not making stuff for your customers.

Revenue / Profit >> Tech

yonixwm
10 replies
9h53m

That’s the problem. In the days of jQuery/Angular2 (and even now personally), React was a blessing. Everyone hoped the same here. We should just join technology a little later on the hype cycle and have less stress.

BiteCode_dev
9 replies
9h35m

React was a blessing for the few creating apps that needed more than jquery, and that AngularJS 1 couldn't handle for perfs reason.

That was actually a very small parts of the projects in the world at the time, and in fact, a very small part of the number of projects that adopted react at the time.

I remember above all that:

- React was hyped to the roof by facebook. They had a fantastic marketing machinery for that.

- React sucked for years, with a terrible doc, a crippling webpack experience and breaking compact all the time.

- The JS community was moving from koolaid to koolaid, never assessing the new tech for their cost. They solely inflicted on the world slow and brittle preprocessors left and right, thousands of stuff you had to integrate manually because "libs > frameworks", and jumped on react, redux, graphql, docker, spa, microservices.

So I would say it was a loooot of hype for react, just like it was for graphql.

I'm going to feel like spamming at this point, but, remember when XML was the future?

https://www.bitecode.dev/p/hype-cycles

ctvo
3 replies
8h14m

React was a blessing for the few creating apps that needed more than jquery, and that AngularJS 1 couldn't handle for perfs reason.

performance was the least attractive reason for adopting React. React introduced composition as the default way of thinking about UIs to the web. You created components and used them to build more complex components. Data was immutable and flowed in one direction (parent component -> child component).

Comparing the above to ng with its dependency injection, MVC style approach to UIs, that used HTML based annotations and tags to sprinkle in functionality (`ng-if` baby) -- it was a much more simple way to build web applications.

React's style of building UIs has largely won. Vue, etc. all follow this component with composition view of the world.

React sucked for years, with a terrible doc, a crippling webpack experience and breaking compact all the time.

Webpack has nothing to do with React. React has always had good documentation. The reason the documentation was good in the beginning was because the API surface area was tiny compared to Backbone, Ember, ng, etc..

I'm not going to go point by point here. You sound like you have a very superficial understanding of the space.

I'm going to hard pass on clicking a marketing link to your blog.

BiteCode_dev
2 replies
7h53m

The simple fact you say

React has always had good documentation

Tells me you rewrite the entire history.

In fact, for years, react didn't even tell in the doc you could use it without a transpiler so people had to learn a whole build chain before even getting to the hello world.

At this stage it's not "superficial understanding of the space" this kind of comment is guilty of, it's total denial.

And by the way, we have been doing components for UI way before react was a thing. jQuery could do components. Backend frameworks could do components.

As for immutable data, I've seen more small projects die from the small cuts of trying to maintain that purity that I've seen those exploiting the benefits like free time travel.

I assume you've been living HN bubble for too long.

ctvo
1 replies
7h45m

You know you can just check before making these claims. It helps with credibility.

In fact, for years, react didn't even tell in the doc you could use it without a transpiler so people had to learn a whole build chain before even getting to the hello world.

React's original documentation site from June of 2013 (when React was first introduced):

https://web.archive.org/web/20130607085014/http://facebook.g...

JSX is a JavaScript XML syntax transform recommended (but not required) for use with React.

It goes on to explain exactly what JSX is and how it converts to JS functions. Feel free to click around that original documentation site.

Here's the README.md from the commit at the same time:

https://github.com/facebook/react/tree/a41aa76ef36471ba07b29...

You'll notice that we used an XML-like syntax; we call it JSX. JSX is not required to use React, but it makes code more readable, and writing it feels like writing HTML. A simple transform is included with React that allows converting JSX into native JavaScript for browsers to digest.

At this point I would kindly ask you to go away.

BiteCode_dev
0 replies
7h38m

I stand corrected, I'm the one with a distorted memory of the doc.

strken
2 replies
8h57m

XML was genuinely better than fix-width data formats (COBOL) or character-separated fields (CSV, HL7) for most APIs. Hierarchical deeply nested trees of data were the future. Everyone uses JSON or a more industrial format like protobuf/avro/BSON to represent such data now, but it wasn't necessarily wrong to point at XML and say it was an improvement.

friendzis
1 replies
8h12m

The problem with XML is precisely that it is so much more than simple hierarchical, nested trees of data. The fact that in a casual conversation XML is reduced to hierarchical trees of data pretending the rest of XML does not exist more than proves OP's point.

strken
0 replies
7h56m

I'm not pretending anything and I hate XML. I would still rather use it than HL7, because it's a hierarchical tree of data and HL7 is not. OP's point is that almost nobody wants to use XML anymore; my point is that almost nobody wants a Ford Model T as their daily driver anymore either, and yet it was still the future, in a certain sense.

Izkata
0 replies
7h59m

React sucked for years, with a terrible doc, a crippling webpack experience and breaking compact all the time.

Webpack wasn't how it started, remember gulp?

Also don't forget the switch from class components to functions, then inventing "hook" functions to reintroduce functionality that already existed in the class components.

For the past few years I've been on a team that handles a legacy system from long before React existed (internal) that just renders HTML directly, a client website that uses Backbone, and a newer client website that uses modern React. The old internal one that doesn't use any frontend frameworks has been by far the nicest to work with, and Backbone the worst.

I think that's some missing context as well - React+Redux was much better than what came immediately before it, for complex web apps. But when you're not building something like that, yeah, both are worse. It just doesn't seem like the Backbone era encouraged people to use it for everything, unlike React.

Capricorn2481
0 replies
7h32m

React was a blessing for the few creating apps that needed more than jquery, and that AngularJS 1 couldn't handle for perfs reason.

React solved a very specific issue that was a pain in Angular, which is making it easy to write small, self-contained components and attach them to a mostly static site. That people decided to use it to make entire SPAs further illustrates how much easier they found it than other solutions.

I can't think of a case where JQuery code is ever simpler than React code, even for small things. If you need to worry about the order of rendered items or moving them into different categories on a page based on input, it's much simpler in React.

projectileboy
3 replies
9h34m

Exaaaactly. I worked on big systems at a very large retailer, and at a very large bank, and in each case, there were reasons why GraphQL worked very well for us. But 90+% of developers across the world adopt tools and technologies because they look fun and shiny, not because they need it. For the overwhelming majority of developers (who in most cases are working at medium-to-large-sized companies on internally-facing apps with a small number of users) a simple web app stack from 2005 will serve you quite nicely.

dopylitty
2 replies
8h53m

I wonder if this phenomenon happens in other industries as well.

I can't imagine a road crew getting away with spending an extra year to build a road because they decided to use completely nonstandard equipment that doesn't work well for the task or they don't know how to operate. I especially can't imagine the road crew screwing up multiple jobs in a row because they change equipment every time they're starting to understand the current equipment.

Maybe it does happen though and I just haven't seen it since I'm not in that industry.

swader999
0 replies
8h4m

Construction is always the wrong metaphor for sw dev.

Think more like marketing campaign or product design.

randomdata
0 replies
6h3m

I don't know about construction, but as a farmer it's pretty natural to look at what your neighbours are doing and if they adopt a new technology in their operation you're at least going to give some thought to doing the same.

But I think it comes with a lot more reluctance and skepticism. You are not likely to jump in head over heels, and even when you do give it a try I expect most farmers will do so with the attitude of "if it doesn't work at least I can always go back to the old way".

The "OMG this is amazing and will solve all of my life's problems" attitude I see in tech certainly isn't there in my experience.

Jeema101
2 replies
9h0m

I think an aggravating factor in the software world (that's maybe not as prevalent in other fields), is that developers tend to want to use the latest and newest technologies, even if said technology is not really appropriate for the task. It looks good on your resume to say that you used the same technology Facebook uses - the ol' "resume driven development".

the_real_cher
0 replies
7h0m

Jobs ASK for that B.S. Instead of hiring a generally capable person that can learn everything during an on ramping.

So devs respond in kind with equal amounts of bullshit.

It's a cycle of bullshit in the industry.

herpdyderp
0 replies
8h48m

You also usually need to actually try out a new technology to know if it’s going to help you. Less “must use the latest tech” and more “let’s see if this latest tech is helpful”. Of course, both happen.

zer00eyz
13 replies
12h23m

GraphQL is the peanut butter to Reacts chocolate at FB.

It works there because

1. Every user is logged in. Is there anything you can do at FB without giving up something to the Zuck?

2. Because it's all behind a login, you can front load the first login/request with a giant SPA and then run all the custom queries you want.

3. everything at FB is some sort of blended context (my user, someone else's user, a permissions interaction)... security is baked in to every field.

4. Because of permissions, and login requirement it's hard to be a bad actor (FB just locks you out, nothing is public).

If you have a SPA and logged in user requirement and that robust permissions model then GraphQL might make sense... Otherwise its a shining example of conways law and might not be fit for your org... The same can be said for react too.

UweSchmidt
4 replies
11h36m

What if Facebook wanted to open up parts of the site for users without an account, would that require a major reengineering? I've wondered why Facebook (and Instagram) are so strict about not showing anything to logged-out users, could technical reasons be part of that decision?

tomlong
1 replies
11h33m

I think this currently exists in some shape or other, I don’t have a facebook account but I can click on profiles of businesses and get their opening hours and pictures of their menus or whatever. In think there must be some stuff with a public context.

9dev
0 replies
11h23m

My guess would be they SSR those pages and partially hydrate the page on the client if the user is logged in.

dumbo-octopus
0 replies
7h44m

Are they? I have full access to all the Instagram reels, posts, comments, etc. friends send me, without being logged in.

Kwpolska
0 replies
7h32m

Not really, it’s 100% business reasons. Facebook and especially Instagram used to be much more open to logged-out users in the past.

jamesrr39
1 replies
11h46m

presumably there is still some authorization requirements though? The logged in user is authorized to see details about Friend 123, but not about Non-Friend 456?

andrelaszlo
0 replies
11h30m

That might be what they meant by "robust permissions model".

graemep
1 replies
11h11m

FB have a lot of resources to manage the complexity of this.

For most people "security is baked in to every field" is going to be very expensive.

zer00eyz
0 replies
11h4m

Candidly, I think a lot of the "security" is baked into the data model of what FB is... Are we linked on the graph, are we linked directly, what do your permissions allow me to do based on that relationship. It isn't a difficult query to wrap most requests in. I dont think FB needs that many people keeping an eye on this.

That having been said, outside that data model, your absolutely correct that its going to be costly to maintain those extra layers of relationships.

daxfohl
1 replies
5h29m

Does TAO help? I imagine it's a lot easier to embed all this additional logic and metametametadata in a single service than distribute.

gaogao
0 replies
27m

Nah, it's one level up having basically everything as an Ent (ORM object) with an associated data access policy that does that.

BiteCode_dev
1 replies
9h45m

No, GraphQL makes sense at facebook because at their scale, dealing with the consequence of allowing all possible queries was less work that having to create dedicated enpoints for all the possible client queries.

People completely missed the point of GraphQL, which is you TRADE flexibility for the client for added cost on the server.

Which in a app and team as huge as facebooks' made sense, especially since they have the so-called facebook apps that could do... anything.

hot_gril
0 replies
5h44m

Yep, GQL can make sense if you have tons of clients.

mst
7 replies
9h27m

Seems like at that point exposing each query as an OpenAPI endpoint would achieve pretty much the same thing.

Then again having GraphQL as the definition for them is probably still not bad, I'll just have to write something that converts them to SQL::Abstract 2 trees once I get around to porting it to TS.

dventimi
6 replies
8h27m

It would be the same thing except with Benje's approach, you're basically using GraphQL as a developer tool to create those end points instead of writing code to do it.

And you don't have to write something to convert them to SQL if you're using PostgreSQL, because Benje's already written it for you.

mst
5 replies
6h46m

postgraphile does look like it'll handle basic cases pretty nicely but I've gone through the docs and didn't find anything like an explanation of what SQL queries it ends up mapping to - do you happen to know if there's one I missed, or a list of examples of GraphQL + corresponding SQL, or something?

dventimihasura
4 replies
5h55m

PostGraphile compiles GraphQL directly to SQL. The SQL is "custom" in that it's specific to the GraphQL operation, though naturally it does follow rules. For example, Hasura does the same thing, and among the rules that it follows is that it uses `LEFT LATERAL JOIN` between tables (at least, on PostgreSQL). Full disclosure, I work for Hasura, so I'm not super familiar with the style of SQL PostGraphile generates but one thing you can do is just have PostGraphile report back the generated SQL for inspection:

https://www.graphile.org/postgraphile/debugging/#via-postgra...

dventimihasura
0 replies
4h15m

Nice!

mst
1 replies
5h4m

PostGraphile compiles GraphQL directly to SQL. The SQL is "custom" in that it's specific to the GraphQL operation

Yes, that's why I said GraphQL and -corresponding- SQL, I was hoping to find something that showed me the SQL for each of half a dozen or a dozen examples ... though the debug option there will let me point the out-of-the-box CLI at a pre-existing database and have a look at as many examples as I like, so that's pretty close to what I was looking for.

Would also be interested to see a bunch of examples of what Hasura generates if you have those to hand (I'm going to poke through the Hasura Community Edition docs but if you have the specific FM to R handy ... :)

probabletrain
8 replies
10h2m

What about the benefits/drawbacks of the graphql client in a web app, e.g. Apollo [1], Relay [2]? You get a client-side normalized cache of all data fetched by any query. Here's a handful of benefits:

- If data already exists in cache, a query will return that data instead of making a network request.

- Everything that has a data dependency on something in the cache will automatically update when the data is updated, e.g. after a mutation.

- Cache data can be optimistically updated before the request completes, UI that queries this data will automatically update.

- Components will automatically refetch data if they need to, e.g. if an object is partially updated.

The pain points are pretty painful though:

- Really hard to debug unexpected refetches.

- Normalizing the data for the cache comes at a cost, it can be pretty slow for big responses.

- You quickly realise you need to really understand how the client works under the hood to be productive with debugging/complex behaviour.

I see it as a case of "this is the worst API/client, except for all the others". I'm curious to hear how people using non-graphql APIs are managing data in the client in web-apps with complex data needs?

[1] https://www.apollographql.com/docs/react/why-apollo [2] https://relay.dev/

shepherdjerred
1 replies
5h18m

TanStack Query isn't a REST client. It's a generic data fetching framework.

You could use TanStack query with GraphQL, Apollo, REST, or any other data source.

travellingprog
0 replies
4h43m

yeah, you're right!

romanhotsiy
1 replies
8h34m

We use https://tanstack.com/query/v3 + openapi-based auto-generated SDK.

I would say the DX is pretty much comparable to using Apollo Client.

shepherdjerred
0 replies
3h20m

What do you use to generate your SDK?

WiseWeasel
0 replies
7h24m

Except it only has a query-based cache, rather than a normalized cache by type name and ID. This means a deeply nested component running a mutation to update an entity can’t update the state of a component a few levels up purely with the response to that mutation, it instead needs to invalidate the cache and cause the parent to requery, much less performant.

martpie
0 replies
5h49m

To me, the best feature is Relay Fragments (I think Apollo has fragments too?), as each component describes the data they need: no need to do a big top-level request then pass down the data to the responsible components, everything is in one file.

It makes UI changes much much easier to deal with.

hot_gril
0 replies
5h40m

I use Express for my web server and OpenAPI for the schema, which works like a charm.

noduerme
7 replies
11h44m

Haven't used GraphQL but the idea of exposing queries from the client directly to the DB is totally bananas, even behind a login with a separate auth. Even just explaining your DB structure is a thing you should not do.

rockyj
2 replies
11h39m

Not a fan of GraphQL (the problems mentioned in the post are very real), but GraphQL specification does not say anything about the DB design / queries. It is still an API layer and you are free to model it in any way you want.

discreteevent
1 replies
10h1m

Indeed, from one of the authors of graphQL on this very forum:

"That would be one way to implement the system in a DB-centric way. However we believe that intermediate application code is pretty critical to any GraphQL implementation." [1]

"GraphQL is a client-server dance that needs server-side capabilities, not just CRUD semantics." [2]

[1] https://news.ycombinator.com/item?id=9879870

[2] https://news.ycombinator.com/item?id=14351800

dventimi
0 replies
7h16m

I do not share that author's belief about application code.

trallnag
0 replies
4h25m

Usually you put in views between your "private" DB structure and GraphQL

manquer
0 replies
11h40m

Graph models need not be your tables . They should reflect your data models, the same kind of models that would have been exposed in a traditional RESTful API?

Similar concepts of allowing queries and response formats was there in other standards and not new ?

OData is fairly popular in REST world , even older , SOAP XMl had supported with custom query language one robust one I remember T-SQL used in Taleo the old Oracle hiring software

There are many examples of clients doing joins and queries in other standards , it is hardly unique to GraphQL

cultofmetatron
0 replies
11h33m

thats not a graphql thing. my startup uses graphql and it does not map anywhere near closer to 1:1 with our database. what you're talking about is the litany of RAD api backend apps that take your db and expose a graphql endpoint.

Xcelerate
0 replies
10h42m

the idea of exposing queries from the client directly to the DB is totally bananas

I don’t necessarily disagree but going to play devil’s advocate here on this common foundational viewpoint. Why is this bad? In fact, why not expose the DB directly to the client?

“Additional layers” and “don’t explain DB structure” is security through obscurity. If a DB manages access control directly (field-level or partition-level granularity), any permissible query should run. To prevent pathological queries, add role-based resource quotas and back-off policies.

What about zero day vulns? Well these are going to be a problem regardless of the presence of various infra layers on top of the DB; you’ll have to monitor for data exfiltration to detect these types of attacks in either case.

There’s not a database I’m aware of that handles all of the above considerations, but oftentimes security issues exist in the overlooked gaps that arise between the complex interplay of many dependent systems. If you move the responsibility for security to the DB itself (other than authentication), you’ve removed a lot of the “confusion” that can be exploited, and overall security then depends on just a few factors: 1) correct assignment of DB access permissions, 2) valid external authentication, 3) quality of data exfiltration monitoring.

You might say you’re one simple DB misconfiguration away from disaster, but again, this is already a problem. The benefit of this alternative approach is that you have now shifted the bulk of the security work to one place: very careful rollouts of changes to DB access permissions. You would conduct static analysis to determine the “diff” of how data access has changed and perform sandbox tests. In exchange for this additional work, you can quit worrying about the security of anything downstream of the DB, assuming authentication is set up correctly.

jvans
7 replies
10h56m

Additional graph pain points I'd add:

Reliability:

* Not null fields in a distributed system are a lie. Clients write code assuming something is not null, so a query that fetches data from N sub systems breaks the entire page when one of them fails.

Performance:

* People say you only need to fetch just what the page wants but in practice clients create re-usable fragments for every object in the system and use it everywhere. Any time a new field is added, every api call fetches that new field adding latency everywhere

* clients are unaware of the underlying topology and add fields that are usually harmless but have bad tail latencies.

* The completely generic nature of the API means the backend can't optimize performance for a specific page. E.g. if one API has nasty tails, but it's not that important for this page, the backend could time it out at some reasonable value instead of holding up the entire request

RedShift1
4 replies
10h28m

* Not null fields in a distributed system are a lie

If something is null that's not supposed to be null, then the entire operation should be called into question. It's probably not safe to proceed so it's a good thing he entire page breaks, you don't want users to continue based on wrong information. If you define something in the schema that it's possible that it's null, but then the frontend dev ignores the fact that it can be null, why is it GraphQL's fault then that the page breaks?

* clients create re-usable fragments for every object

As a frontend developer I don't know why you would do that, but if your frontend devs are doing that then yes they are doing it wrong... However switching to REST with statically defined endpoints doesn't solve the over/underfetching problem, but as backend developer you do get to gatekeep that aspect. So yeah the devs should really be just doing it right.

brabel
1 replies
10h8m

About nulls: you're right, but because of authorization, everything can be null - if you don't have access to something, we need to remove it from the result (instead of just throwing an error, as you may still get enough information to do what you need to do) - and that will always be a fetcher error in GraphQL if the field was non-nullable. And because you shouldn't really know or care beforehand which fields may be "hidden" from the end user due to authorization, you need to make everything nullable or risk making a breaking change later.

daxfohl
0 replies
5h26m

Same thing in sql. Non null guarantees are great until you do a left join.

merrywhether
0 replies
5h53m

In my experience, nothing other than nullable DB fields should be nullable in the GQL schema. Everything else like inter-service problems, auth problems, etc, should be modeled as “result boxes” via union types (somewhat equivalent to Maybe/Optional types). This lets your schema model possible failure cases via strong types without ambiguity and results in resilient front-end code.

Note that the error types added to the union should only be as granular as relevant to the client. Most places will be just Foo | FooNotFound | FooError because your UI doesn’t care why there was an error and you don’t want to unnecessarily leak backend info when it’s not relevant.

I wish this was more strongly recommended in the GQL org docs, because so many people learn it the hard way and migrating is not easy.

jvans
0 replies
8h50m

The problem with not null is people classify them from a domain perspective and not from a distributed systems perspective where basically everything can be null but only some fields mean rendering the page is impossible. It also depends page by page what fields make it unrenderable

yonixwm
0 replies
9h48m

GraphQL really did not handle fragments nicely. Why do you have to create subclasses for each use case and not just put your desired field name…

probabletrain
0 replies
10h25m

clients create re-usable fragments for every object in the system and use it everywhere

I quite like Relay's pattern where components define their data requirements, and this is passed up the component tree to some query at the root. Avoids a situation where the query defined at the root asks for unnecessary fields because it's so far away from where the data is actually required.

https://relay.dev/docs/principles-and-architecture/thinking-...

abound
7 replies
9h13m

Having worked extensively with OpenAPI, GraphQL, plain JSON/HTTP, and gRPC/Buf Connect services, most of this rings true for me.

One thing the author doesn't mention is that you can limit the set of queries clients can call in a GraphQL service, by hash or signature. This mitigates a lot of the gnarly performance and security issues because the attack surface goes from "arbitrary queries" to "queries you've already 'vetted'", where you can look at things like complexity, ACL behavior, etc ahead of time. Since clients (in my experience) aren't usually modifying GQL queries at runtime, this is a pretty good tradeoff.

All that said, I find Buf Connect to be the best set of tradeoffs for most projects: strongly typed servers and clients, strong ecosystem support around protobuf (e.g. to generate an OpenAPI spec), a standard HTTP/JSON interface for easy curl et al compatibility, etc.

OpenAPI as the source of truth is annoying because it's too flexible, and it's rarely possible to generate type-safe servers + clients from an OpenAPI spec without running into one edge case or another.

troupo
1 replies
4h22m

the author doesn't mention is that you can limit the set of queries clients can call in a GraphQL service, by hash or signature.

Then it's just REST with extra steps and none of the benefits

nielsole
0 replies
1h12m

As this is being downvoted can someone explain why this wouldn't be true? One of the core tenets of graphql was not having to involve the backend team, wasn't it?

culi
1 replies
3h4m

GraphQL is meant to be used along side a very smart client-side cacheing library like Apollo

The best practice for GQL is to make frequent, small, queries (Apollo handles batching them) throughout your application. Apollo won't do any extra work to fetch new fields if they're already in the cache

Not to be that person because I understand there's always edge cases, but in general with GQL if your queries are highly complex or too nested "you're doing it wrong™"

feoren
0 replies
42m

"Make frequent small queries and let a smart cache do the right thing every time" sounds like "make a perpetual motion machine". It just sounds like a fundamentally difficult problem with unavoidable tradeoffs. I admit I don't know the details of Apollo, but I find it hard to believe that a caching layer magically solves everything without introducing very gnarly bugs. A cache layer makes concurrent editing harder, for one.

pants2
0 replies
3h41m

Buf Connect or any RPC design really is great. I'm sick of REST too. No more endless discussions about how to make this endpoint the most RESTful or how to cram a feature into REST that doesn't fit. "Oh you need an endpoint to hibernate the server? Just POST a new Hibernate object to the /api/v2/hibernations service."

No. With RPC we can just make a HibernateServer call and be done with it.

ko_pivot
0 replies
7h2m

+1 for Buf Connect. Great CLI, simple codegen configuration, basically no added runtime complexity — it’s just the serialization layer at that point. It’s also great to be able to use it for both the API layer using JSON while also allowing full gRPC inter-op between backend services, with the same library and workflow.

derekperkins
0 replies
5h11m

Huge fans of Buf Connect. We run vanilla gRPC servers on the backend and have a typed experience through to the frontend

theK
6 replies
7h45m

Fine article describing the weak points of GrahQL. I find it a bit poor though that the only recommended alternative is OpenAPI rest APIs.

I have no beef against doing REST, jsonRPC etc. Actually I consistently steer people that way. But the documentation format we chose as an industry to build these things with, Swagger, is just disappointing. Some times I think the industry would be at a totally different point had we gone with more powerful standards like API blueprint (or maybe raml).

Case in point, I'm consulting an org with roughly 1k engineers right now on improving their API ecosystem and what we are seeing is that the more OpenAPI tooling they use, the worse the DX gets...

tommica
2 replies
7h30m

I find it a bit poor though that the only recommended alternative is OpenAPI rest APIs.

What are your recommendations? gRpc?

theK
0 replies
6h58m

My rant, as evident after that sentence, is about the industry selecting to standardize on Swagger instead of emerging a more powerful/succinct/etc system.

bbkane
0 replies
6h8m

Someone above recommended https://connectrpc.com/ , which looks quite promising to me. Maybe I'll get time to play with it today

foobarian
1 replies
7h28m

But the documentation format we chose as an industry to build these things with, Swagger

This right here is IMO the biggest advantage of a GraphQL system. What equivalent to GraphiQL is there for OpenAPI? With GraphQL my frontend devs can go shopping for data in one UI, with rich descriptions and strong typing and even try out the queries live.

ComputerGuru
0 replies
7h21m

You are summarizing the very reason for its existence and popularity: everything is about making the frontend dev’s job easier, at any cost. This is a common theme across the entire web-adjacent industry and has been responsible for plenty of misguided changes and choices.

luke-stanley
0 replies
6h34m

They did address that point specifically, suggesting TypeSpec as a more concise analogue. Presumably converting between them isn't that hard. A more concise DSL could be acceptable. Presumably it can be converted automatically anyway.

dgb23
6 replies
10h27m

One of the major issues I have with GraphQL from the get go is that it introduces it's own syntax instead of using a commonly understood and established _data_ format like JSON or similar.

Same problem with Prisma Model definitions and other such things.

Please, if you make a new thing and it fits neatly into a data format, use a data format! Let me use all of those well established libraries, schema definitions and programming concepts in order to generate, parse and make sense of your thing. Let me seamlessly write your language with the data structures I already know in my language if that's possible.

Don't make it pretty, make it usable.

doctor_eval
5 replies
8h49m

What do you mean? Both GraphQL queries and results are JSON. The query expression is just a json string. Are you referring to the schema language?

Izkata
3 replies
7h52m

From https://graphql.org/learn/queries/

This isn't even close to valid json:

  {
    empireHero: hero(episode: EMPIRE) {
      name
    }
    jediHero: hero(episode: JEDI) {
      name
    }
  }

mdaniel
1 replies
5h4m

and I strongly agree with GP because those arguments <https://graphql.org/learn/schema/#arguments> can get to be insaneo with anything other than simplistic "episode: EMPIRE"; I regrettably can't link directly to it but https://docs.github.com/en/graphql/reference/objects#:~:text... shows that stuff can start to be more than the interior field selection, to say nothing of schemas that define complex typed arguments e.g.

  type Starship {
    id: ID!
    name: String!
  }
  type CaptainQuery {
    captains(starshipFilter: [Starship!]): [Starship]
  }

  # leading to
  {
    captains(starshipFilter: [{name: "Alpha"},{id: "cafebabe"}]) { id }
  }
which I recognize is most often fixed via variables but when the hello-world examples call it out, something has gone awry https://docs.github.com/en/graphql/guides/forming-calls-with...

Izkata
0 replies
4h33m

That has some json-ish embedded inside it, but the query itself still isn't json.

And even the embedded part isn't valid json without quoting the keys.

meowtimemania
0 replies
4h1m

i agree with this. Writing queries is the most annoying part of graphql

nfw2
0 replies
3h36m

They are referring to the schema language

azangru
6 replies
9h20m

Several years ago, I used to respond to conversations where people hated on Facebook by saying that Facebook had given us at least two great gifts — react and graphql. Since then, I've grown to realize that these might in fact be its two great curses.

chrisandchris
5 replies
9h17m

What do you dislike about React?

azangru
4 replies
9h2m

Performance. Alex Russell, formerly of Google and now the product owner of Microsoft Edge loves to rant about it. His latest rant is how Edge has significantly improved the performance of some of its UI features by moving off React [0].

[0] https://blogs.windows.com/msedgedev/2024/05/28/an-even-faste...

yCombLinks
0 replies
4h22m

The options we have today are not the options we had at the time Facebook introduced React. React solved tons of browser shortcomings that are finally being fixed in the actual browser.

chrisandchris
0 replies
7h10m

As I read this thread, it's not like "React was the issue, let's move to [other framework]", it's more like moving closer to the plattform brought a performance boost.

And that's something I would totally agree. Moving from WebUI to native UIs would even be more performant, and if one would care that much about performance (as said in the thread), one would probably not look at WebUI/Electron/Browser at all and prefer native apps.

nesarkvechnep
5 replies
11h28m

Whenever you see REST in the article, think RPC. The author even says REST is simpler than GraphQL but I suspect they hadn’t implemented a REST API… ever.

9dev
3 replies
11h22m

What is that you find so complex about RESTful APIs?

DanielHB
1 replies
10h54m

Pure REST API is a huge pain in the ass to use and leads to bad performance because of waterfall requests. It is like the number one thing GraphQL solves for most people, decide which nested relationships to inline into a response.

The simplicity makes it bad to use, if you work around the simplicity (arbitrary inlining, extra fields to choose what to inline, etc) then you end up with non-standard complexity.

nesarkvechnep
0 replies
9h21m

Bad performance if you haven’t heard about HTTP caching. REST implies cacheabality.

k__
0 replies
11h6m

I assume, it's less about the complexity and more about most people not understanding REST.

baq
0 replies
11h9m

I’ve done it once in my two decades of being paid to code and only because it was small enough to not impact any timelines… nobody cared anyway. Otherwise REST now means ‘RPC over HTTP with JSON marshaling’ for better or worse.

chuckadams
5 replies
6h18m

I must be the only one who found GraphQL, used it in a small project, and liked almost every bit of it. I used Apollo Client and graphql-codegen to generate types and functions for Vue 3, and nothing else could touch it. It wasn't all smooth sailing of course: I did find defining new scalar types to be fiddly, and I couldn't really even make proper use of union types, directives, or even enums due to the impedance mismatch of Apollo Client (JS) and API Platform (PHP). The latter had a lot of nice features in implementing the API backend itself, but the poor documentation for its graphql support held me back. But even the super-basic graphql subset I did use caught a great many errors at the type level where other solutions would not have.

These days, given the freedom to write the backend in TS too, I might look into tRPC instead. One thing's for sure, I won't be going back to OpenAPI unless and until I can fully autogenerate api.yaml and otherwise never have to touch it again (getting there with zod+openapi on another project, but it's nowhere near as easy as graphql-codegen doing all the things with one introspection query).

drpossum
2 replies
4h40m

used it in a small project, and liked almost every bit of it

This is the difference

chuckadams
0 replies
4h24m

Perhaps, but isn't everybody saying it's strictly for the Billion-User Big Dogs? I admit I'm a small-timer nowadays, but having been a cog in a couple mega-corporate machines, I would have walked over my grandmother to get the strongly-typed tooling I get with graphql.

Hamuko
0 replies
4h29m

I don't know, I used GraphQL in a small project and I absolutely hated it. I mean, it was definitely workable, but I just absolutely hated writing those queries. Why am I having to write these again? It's not my website, so why am I in charge of writing the API?

moribvndvs
1 replies
5h28m

After building several GraphQL-based applications, the design time experience and expressivity offered to UI developers particularly when the application is first starting out feels really great. But like the author, it sours quickly after that.

I found myself spending a large amount of time inventing and trying to patch in solutions that most RPC and REST frameworks solved long ago for both the server AND the client (auth, rate limiting, error handling and validation stick out particularly). Client solutions are comparatively heavy, complicated, and riddled with gotchas (e.g. caching) that trip up new team members more than REST. It’s not impossible to build performant GraphQL solutions, but the solutions feel more like afterthoughts and require more vigilance to ensure your team doesn’t stick their finger in an electrical socket compared to REST. The lack of namespacing or organization results in almost unintelligible query and mutation documentation for large projects. The comparatively large size and complexity of requests can be a headache for ops teams. I loathe that interfaces and inheritance don’t work for mutations. Front end devs just use it like a very heavy REST and the holy grail promised by stuff like Relay never materializes. I could go on.

And at the end of the day, the app’s API usage will stabilize and mature, and the expressiveness becomes less compelling compared to its cost. When I went back to OpenAPI and REST, it was like a breath of fresh air, I felt I was building things much faster. I will grant you that generating clients from OpenAPI still is the worst part.

chuckadams
0 replies
4h14m

(auth, rate limiting, error handling and validation stick out particularly)

I got all that for free with API Platform because it's based on Symfony. Ironically it's the graphql implementation that's primitive [1] -- but rock solid, so it won out, and being a rank newbie at GQL when I started, it was probably best I was stuck with the basics.

The JS backend world is a lot more ad hoc than the modern PHP world, so I can picture a lot more nightmare integration scenarios there. Besides, I'd probably prefer using tRPC + zod for my next all-TS project.

--

[1] - It's actually pretty sophisticated underneath, but the code is a loosely-documented architectural maze, so yeah.

aurareturn
5 replies
11h51m

I never got into GraphQL. It always felt like a lot of complexity for little gain (I'm full-stack). People always jump on tools created by tech giants but they solve different problems than the vast majority of companies.

oksteven
4 replies
11h45m

agree, it solve problem at FB for sure, that is a good point.

romanovcode
3 replies
11h43m

Same with Redux. Solved problem in FB. Increases complexity tremendously for 90% of other websites. I remember seeing the tutorial being showed in Todo app and thinking "wtf is this garbage needed for here".

I'm glad Redux hype train is over and nobody is using it on new projects no more.

dgb23
1 replies
11h27m

I think the hype is mostly over because of useReducer. It's the simplest thing that lets you structure your code in the way you want if you'd had chosen Redux (or similar).

aurareturn
0 replies
9h43m

I’ve also switched to using useReducer.

hot_gril
0 replies
4h51m

If it takes more than a minute to understand how a single button example works, one should give up. Maybe some day I'll come crawling back to Redux, that'll be fine, but so far it hasn't happened. Same with Angular.

vitiral
4 replies
8h38m

I've read the article and a few of the responses but have never used GraphQL. However I have a question

Would it be fair to say that GraphQL is extremely useful for internal-only clients? For example an inhouse data store, query service, test status monitor, etc?

So many issues disappear when you aren't concerned about bad-actors and you have _some_ control over both client and server.

diggan
1 replies
8h10m

Would it be fair to say that GraphQL is extremely useful for internal-only clients?

Compared to what? If you're feeling really safe about the "internal-only" parts, just expose an endpoint to allow SQL (read) queries and you'll get essentially the same thing, especially if your data store already is SQL-like.

vitiral
0 replies
3h43m

And GraphQL has no real benefits over SQL? If so... I'm not sold

crabbone
1 replies
7h50m

Just use SQL? A much better language with saner semantics overall.

My first and last impression from GraphQL were that whoever wrote it hadn't had a chance to work with other query languages. A lot of the problems OP mentioned were quite on the surface. Had you ever used ORM, you'd be very intimately familiar with N+1 problem. Had you ever encountered SELinux, you'd be painstakingly familiar with authorization problems. Had you ever worked with XML (especially schemas), you'd be aware of parsing problems created by exploiting recursive properties of the grammar.

To me, GraphQL feels like a project by someone who is very enthusiastic, but lacks experience. If you need more examples of the same: the Terraform configuration language (not sure what it's called), Neo4j query language (I think it's called Cypher), libconfuse, Protobuf, and many, many more... unfortunately.

vitiral
0 replies
3h41m

Protobuf

Google's entire software backbone is literally built on this haha. There are things about it I don't like, but it DEFINITELY scales

eatsyourtacos
4 replies
6h41m

I only have one experience with a client using GraphQL and it was horrendous.

My biggest complain is there seemed to be no way to just to query all fields. I know that is intentional and the point of GraphQL.. but they should support something for the server side to enable this. Maybe they have over the years, I don't know. But my experience was during the implementation phase the client kept adding new fields that I didn't know about and then I had to constantly ask them for the fields because I thought I was missing data. If I could have just queried ALL the fields, then saw what came in, and chop them down to what I need.. great.

The only way GraphQL seems to make any sense is if everything is basically completely defined and you are at a final project stage. After many many years of experience... this is rarely the case.

Cool piece of technology? Sure.. but hardly practical except in scenarios of extreme amounts of data and only when it makes sense for the client to return specific fields.

Although I think still for 95% of even those extreme cases, you just write a REST endpoint that returns the fields that make sense for the query....

tossandthrow
1 replies
6h37m

You should have looked at the schema.

It indeed seems like GraphQL saved your client in this case.

eatsyourtacos
0 replies
5h34m

It indeed seems like GraphQL saved your client in this case.

Yeah.. no.

steve_adams_86
0 replies
6h35m

I think you’re right about it being suited to well-defined scenarios. But I agree too that a regular endpoint to get specific data is more often than not totally acceptable. I’m not aware of many situations where the flexibility of graphql is as useful or important as the demands it places on a team.

I worked on a team where 3 of us were well into our second decade of software development, yet we still had a consultant come in to help us sanity check our graphql implementations and ongoing strategy.

We were mostly on the right track. The struggles we were having were just… Normal.

At that point I really lost steam. Prior to that I was motivated by the thought that something wasn’t clicking yet. Discovering that I understood graphql just fine but it was typically a bad developer experience with obtuse tooling and queries took the wind out of the sails.

The worst part was mutations.

Writing graphql handlers in Rust was also awful. The more you try to leverage the flexibility of graphql, the more Rust freaks out because you’re doing exactly what you shouldn’t in such a strict environment.

Yet… Doing this in a language with weaker typing and less strictness seems like a potential minefield of bugs.

I see the appeal of graphql and I’ve liked it in small one-off situations where it was useful but had limited scope. Otherwise I genuinely hope I don’t work with it again.

mdaniel
0 replies
4h58m

I am for sure no graphql ninja but I believe what you are describing is achievable via the introspection call, which the sibling comment hints at when mentioning the schema but I'm saying that's a runtime call just like any other and thus no "reading" required. I do think that introspection stuff is opt-in because some shops consider it an information leak vector, but for dev/staging I think it's a perfectly fine tradeoff

https://graphql.org/learn/introspection/

dventimi
4 replies
8h43m

I generally agree and am likewise "over" GraphQL. Having said that, I disagree on some of the finer points.

First, some of these issues--authorization, security, N+1--can be mitigated by using something like Prisma, PostGraphile, or Hasura, instead of crafting GraphQL backends with code.

Second, there are gains to be made by compiling a GraphQL operation to a single operation in the underlying database's query language (e.g. SQL)--when that's possible--rather than by following the "resolver and data-loader" catechism.

Third, as I've written elsewhere recently, I think the N+1 problem is overblown. Not that it doesn't exist, but just that it only sometimes exists and usually isn't as bad as is often claimed. But again, this is eliminated by switching to a compiler approach anyway, so it's not worth making a federal case over it.

Despite all this, like I said I'm still over GraphQL. If you must implement it, try to use one of the tools mentioned above if you can.

gmassman
1 replies
5h58m

I don’t want to overly generalize, but N+1 problems are very real and frequently occur in code written by more junior developers. Their impact and occurrence rate are dependent on the nature of the application though.

I also think there’s an avoidance to simply “translate” a GQL query into an SQL query. Not that it can’t be done, but it allows a lot less flexibility in the backend as far as code patterns that can be adopted. Basically it minimizes the use of ORM models, which may be a pro for some and a con for others.

I haven’t worked with GraphQL in over 4 years since I left my last job. I actively made a choice not to use it at my current job and steered the ship towards REST endpoints, mostly because it would be easier to build authorization middleware. Also like the author of the article discovered, code littered with dataloaders is a pain to maintain.

dventimi
0 replies
5h31m

I grant that the N+1 problem is real, but I reject that it's always a serious problem. That's what I mean when I say this it's overblown.

I'm not persuaded there's an avoidance of translating GraphQL. Rather, I think it's largely because of a lack of awareness of that as an option. Most or all of the material written on the subject exclusively presents execution as matter of nested resolvers and that's how pretty much all the libraries work, so I think it's natural to assume that's the only way to do it.

I will say that translating to SQL does remove a convenient arena in which to write business logic in a general purpose programming language, which generates resistance to the idea of translation once it's encountered. But, as the author says, that mixes business logic with data marshalling code anyway.

aeonik
1 replies
6h15m

N+1 problems were the primary bottleneck in a Websphere backendi worked on for years.

Transactions were being aggregated with thousands to 10s of thousands of SQL statements like this.

    SELECT * from customer
    where id = <single id>
The developers had no idea the ORM was doing this under the hood.

It's trivially easy to say that if every SQL statement took 1ms to execute, that thousands of round trips can really start to tank whatever process it might be blocking.

dventimi
0 replies
6h4m

It's trivially easy to say that if every SQL statement took 1ms to execute

Good thing I don't say that! What I do say is that the number of SQL calls will tend to scale with the volume of data retrieved. Limit the volume of data the user even is allowed to request and you'll naturally limit the extent of the N+1 problem.

RedShift1
4 replies
11h29m

I still love GraphQL, but much of the love comes from using tools like PostGraphile which generates the API for you based on your database schema. I then add my own Javascript plugins as necessary. Going back to REST and hand writing everything gives me the shivers, how much time am I spending just translating data A to data B?

Authorization: I do it in the database using roles, row level security and column level security. It works well and I defer everything to PostgreSQL's security controls, it feels like the right place to do it and I don't have to worry about it going out of fashion, PostgreSQL is here to stay. Anybody else who talks to the database directly is also subject to the same authorization rules, which is nice.

Introspection: this should really be disabled on production services. Only enable it for development.

N+1 problem: I don't really have a problem with N+1 because PostGraphile converts the request into an efficient query. In other cases this problem presents itself in REST too and the article proposes hoisting N+1 queries to the controller, but that's just really moving the problem around, and you can do this with GraphQL too.

The other problems, yeah sure they are present and a worry if you're running some highly visible/very loaded public API.

gatvol
1 replies
10h55m

If you're writing you're REST API by hand I'd suggest that you may not be doing it optimally.

keb_
0 replies
6h57m

How should you write your REST API?

doctor_eval
1 replies
8h39m

Agree with this 100%, Postgraphile is awesome. I started a new project recently and was writing “REST” APIs because I’d been reading that people were put off by GraphQL, but it was a complete pain - instead of exposing my data and querying it as needed, I had to try to guess up front what I should expose in what object. It was the bad old days all over again, writing adhoc code on the server to meet the needs of the client… switching back to GraphQL - and postgraphile - was a relief.

As someone who has used GeaphQL extensively, I really don’t understand most of the complaints, which seem like they’d be common to any complex API surface. Sure you can write a query that triggers a server bug, but that happens with REST too. Yes, your server needs to be hardened against these queries… so what?

And security is hard, granular security doubly so. If you need to do field level authorisation then the problem is that you need a policy engine, not a different query technology.

dventimi
0 replies
7h22m

I think some of the complaints come from using code to offer GraphQL backends rather than just using PostGraphile

BillyTheKing
3 replies
11h48m

GraphQL basically only really works with monoliths that share the same access-pattern (either everyone logged in, or everyone logged out), it's otherwise a pain to merge multiple different graphql-schemas into a single one (or at least I'm not aware of an elegant way to achieve that).. The worst of two worlds is a micro-services back-end with a graphql Api interface, it makes testing individual services and the Api as a whole quite annoying.

I do really like the Api definition part of it though - but I found something like typespec now to be the perfect middle-ground, it allows out you describe your apis similar to a graphql Api without enforcing the graphql engine on you though.

tisdadd
0 replies
7h25m

I remember having to solve the merge in the past and we ended up using a merging tool pretty easily to do so. Believe it was this one? https://the-guild.dev/graphql/tools/docs/schema-merging

We were basically just enhancing an external graph with some of our own stuff added on though so fairly straightforward.

manquer
0 replies
11h42m

Hasura does role based access control pretty well.

Apollo federation and implementation of supergraph and nested graphs is pretty robust

We use both in production at reasonable scale and complexity 10+ roles few hundred object models, 100s of request/sec

kabes
0 replies
1h14m

True, but rest calls over multiple micro services is even worse

pjmlp
2 replies
10h29m

Unfortunately it has become fashionable in SaaS products to only offer GraphQL endpoints, thus whatever we think about it, GraphQL it is.

williamdclt
1 replies
10h23m

I don't interact with that many SaaS products, but I've never seen that

pjmlp
0 replies
9h20m

If you want to be pedantic, some do offer REST or GROQ as well, which aren't much of an alternative anyway.

mirekrusin
2 replies
5h50m

Just use jsonrpc over websockets - you’ll have same semantics as function calling in your programming language, type it if you’re using static type aware lang and have happy life. It’s easy to optimise, refactor, trace/debug, use (same as using library with async functions) etc.

mdaniel
1 replies
5h1m

trace/debug,

for whom? when was the last successful experience you had of telling a product manager to open their devtools and find the row in a websocket handshake showing the actual payload that went over the wire for the timeframe in question?

I am open to the fact that maybe there are super advanced organizations which have replay debuggers or Sentry or whatever that remove the need to utter the dreaded phrase "can you open the devtools?" but I regrettably haven't worked in one

mirekrusin
0 replies
3h26m

Nobody is looking at websocket handshakes. What I meant relates to simplicity around recording communication - req+res+duration and notifications, the fact that semantics are familiar and very clear, it's easy to filter/plot/explore it, everybody knows what is happening, where to optimize etc.

knlam
2 replies
7h4m

Working with GraphQL over 6 years, I have seen (and created) many mistakes mentioned in the article. GraphQL is not great but it has worked well for me, you just need to adapt & change mindset to create better interface for your graphQL endpoint.

For example, having nested queries more than 2 levels is a no go for me (just like having nested inheritance is basically anti pattern)

Focus more on your interface. One way to avoid N+1 and nested query is to required parameter for related fields. For example

```

user(id: $userId) { {

  id

  friends {

    id

    ...

  }
```

to

```

user(id: $userId) {

  id

  friends(id: $userId) {

    id

    ...

  }
```

vvpan
0 replies
2h43m

I have had to implement a large REST API recently and feel like I spent a lot of time setting up things manually that GraphQL provides out of box. REST tooling has gotten better but so far I have not seen anything as convenient as Apollo, for example.

pavel_lishin
0 replies
6h43m

I don't think I understand how that change avoids the N+1 issue. It's still fetching all of that user's friends, no?

jamesrr39
2 replies
11h47m

I agree with the article, and want to add on that the browser network debugging tools are a pain to use with GraphQL (every request to /api/graphql, can't even quickly filter by endpoint name). I landed instead on OpenAPI, which can feel like a bit of a hoop to jump through sometimes when writing endpoints (but then, so can GraphQL), but the result is equally nice. And it's much easier to get authorization right with REST APIs.

I wonder if GraphQL would have been as popular if it was a much smaller shop than facebook launching it. Feels like having a name like FB gets you a tech credibility pass.

silentguy
0 replies
8h27m

There are browser extensions which make it easier to debug grapgql. A new pane is added to the browser debug panel. Last I used them more than two years ago, it was still not as good as the built-in network tab for rest queries. Still better than the default for the graphql queries.

RedShift1
0 replies
11h26m

For the browser network debugging tools: I'm using the Apollo GraphQL client and added a link that adds the operation name into the URL. So my URLs look something like "/graphql?op=getStuff" and my GraphQL queries: "query getStuff { ... }"

SantiagoElf
2 replies
11h21m

Never bothered to learn GraphQL - anything being pushed by big tech companies usually in 80% of the cases works for them, but its an overkill for smaller scale projects.

Stick to tried and true - monolith, asp.net, angular or blazor front-end, relational database.

doctor_eval
1 replies
8h31m

anything being pushed by big tech companies usually in 80% of the cases works for them, but its an overkill for smaller scale projects.

asp.net, angular or blazor front-end

Since when are these not technologies pushed by big tech companies?

A company I worked with got badly burned by AngularJS.

SantiagoElf
0 replies
3h55m

I have used Angular since version 5.

I have never had any major issues or problems with it.

Think of it this way: GraphQL, Docker, and Kubernetes solve problems that very, very, very few GIANT tech companies have, but not every app will scale to millions of users.

Aeolun
2 replies
11h29m

Can only agree with author on all points. GraphQL was nice for the types, and precious little else. But we have better solutions utilizing just the types now, so it was still valuable.

etimberg
1 replies
11h21m

IMO even the types are annoying because null is opt-out rather than opt-in

DanielHB
0 replies
10h47m

The reason it is like that is because GraphQL is intended for highly distributed backend where at any time one of those backend services might be unavailable and failing the whole request when only a single deeply nested field is missing would lead to bad user experience.

In short GraphQL is optimized for keeping as much functionality working as possible no matter how much instability there is in the backend.

This is a common problem in REST endpoints that consume data from multiple services as well. But the request usually fails completely. On the other hand REST request don't usually touch as many services as a GraphQL request.

ttfkam
1 replies
3h22m

The only time I think GraphQL works is when it is when the GraphQL schema and resolvers are autogenerated by the underlying data stores. As a ORM layer, I love solutions like Postgraphile and Hasura where they mostly just reflect the structures you've already designed in your database. I also like REST solutions like PostgREST for the same reasons.

Then I'm designing my table structure, optionally designing my views when I don't want a 1:1 reflection of how data is stored, setting up row-level security at the data layer, and making user-defined functions for the one-offs that deviate from plain CRUD.

But solutions like Spring DGS for Java, Graphene for Python, and Apollo for Node? No thanks. Never again. Way too much trouble and pain. I'd rather make lambdas that talk to the data store directly and output HTML than make and maintain a GraphQL schema manually again.

I really wish Postgraphile and Hasura were more popular, so folks could have skipped the low level plumbing and optimization fences like dataloaders that make GraphQL such a chore otherwise.

It really is elegant when you're not stuck in a swamp.

damidekronik
0 replies
3h17m

Postgraphile is great, until you need to debug row level security. Or when you realize you need another tool to make the query type safe.

thom
1 replies
11h34m

GraphQL always felt to me like it solved the easy part of the problem and offered nothing to solve the hard part. I have a similar response to things like Zanzibar. At the end of the day I want to go and get some stuff out of a database, and that complexity just ends up dominating everything.

ozim
0 replies
11h22m

That is for me gut feeling about AI .. but that is not discussion about that topic.

So in general had the same feeling about graphQL because I still had to write layer of code that gets stuff from database, get it limited or paginated. Maybe once you have enough endpoints then you can change your front end against already existing GraphQL - but for me that was never the case as 90% of work is adding new tables, new endpoints so graphQL feels like additional work with additional footguns for almost no benefits.

surfingdino
1 replies
9h21m

I worked on two projects using GraphQL and don't want to do it again. Both times the backend was a mess and the "design" or the lack thereof had all the signs of being written by "evangelists" who got bored or got fired leaving the new arrivals to sort out the mess. I'm sure GraphQL is the right fit for some problem domains, but most of the problems I deal with are happily solved with the help of a REST API.

electrondood
0 replies
6h5m

written by "evangelists" who got bored or got fired leaving the new arrivals to sort out the mess.

BINGO.

Someone (VP Eng who was a FE dev) 7 years ago decided shiny new thing was the best and we had to use it, it was owned by FE team, then no one wanted to own it, now BE team has to deal with it, and every dev goes out of their way to avoid it in arch design for new features.

Have seen this at two companies so far.

santiagobasulto
1 replies
11h42m

Fully agree with the article. I think the summary is that GraphQL was a great idea from the frontend's perspective, but it was never fully worked out from a backend's standpoint.

dventimi
0 replies
8h25m

Hasura, PostGraphile, and Prisma do make it quite a bit easier for the backend.

rglover
1 replies
5h31m

Worked with GraphQL from 2017 to 2021. It was the last tech "hype" I bought into. At first, it made a lot of sense and the thing that got me was the structure. But eventually, I realized how much extra work and duplication of everything there was. At the time, too, things that should have been easy like subscriptions had a nightmare API packed with weird terminology that made implementing simple features a slog.

The one positive to come out of working with it (aside from knowing how to spot a tech black hole) is that it informed the design of the API layer in my framework [1][2]. I realized the sweet spot is starting with a basic JSON-RPC type endpoint and then layering things like input validation [3], authorization [4], and selective output [5] (only requesting certain fields back) on as you need them.

[1] https://docs.cheatcode.co/joystick/node/app/api/getters

[2] https://docs.cheatcode.co/joystick/node/app/api/setters

[3] https://docs.cheatcode.co/joystick/node/app/api/validating-i...

[4] https://docs.cheatcode.co/joystick/node/app/api/authorizatio...

[5] https://docs.cheatcode.co/joystick/ui/api/get (see output array in the function options API)

hot_gril
0 replies
4h33m

I'd much rather find out the hard way that I need something than find out the hard way that I don't. There was one project where OpenAPI became a bit painful and I rediscovered why GraphQL could make sense, but it didn't reach the threshold.

powersurge360
1 replies
5h21m

I think GraphQL works its best magic when you are building your own unified data access layer for a backend. Your individual services can be backed by Postgres or Mongo or an in memory database, whatever, doesn’t matter. And from there a backend queries that, translates the data into a RESTful one, and passes it along to a front end Backends-for-Frontend style.

In this way services get freedom to define their stack while still neatly fitting into the suite of services, products get a tidy interface from which to query everything, and because the GraphQL consumer is more akin to a regular database consumer, the database muscle memory kicks back in.

I’ve also grown to prefer bespoke backends for each client over a super backend that tries to anticipate all of the needs of all the clients. It just opens too many holes and what it buys in versatility for the client author it also gives to the exploit author.

gedy
0 replies
4h53m

Sounds like you are describing the Backend For Frontend (BFF) pattern and I also quite like it.

nprateem
1 replies
9h21m

I'm surprised it took 6 years to discover these issues. The N+1 problem and auth/field privacy are obvious on practically any project.

In other news, bitcoin will never replace cash, most companies don't need k8s and AGI isn't 2 years away.

dventimi
0 replies
7h20m

The N+1 problem doesn't exist on any project that uses, say, Hasura.

mcdonje
1 replies
6h1m

1. Write a succinct human readable TypeSpec schema >2. Generate an OpenAPI YAML spec from it

Why? Isn't YAML human readable?

emlos
0 replies
5h18m

Yes, but OpenAPI specs tend to be verbose and hard to navigate. Remembering the exact anchor for the type you defined can be difficult, finding the reference can be harder, and you probably won't get any help from an IDE.

I tend to prefer just writing the yaml, but I can also see why these kinds of tools crop up to mitigate the need to remember all the details.

k__
1 replies
11h37m

A few weeks ago, I read that tRPC is an interesting alternative.

welder
0 replies
6h23m

I've been using tRPC for 6+ months on a large web and mobile project with great results. The only downside is you're restricted to using TypeScript on both frontend and backend, but I was already going to do that anyway.

Another library to check out: Drizzle-ORM

jojobas
1 replies
11h31m

It's not graph, and it's not QL.

dventimi
0 replies
7h18m

It is QL.

jakubmazanec
1 replies
10h28m

For web apps (not simple pages), developed by a single full-stack developer, I think the best solution currently is to use Remix's loaders + actions (i.e. no need to create separate API layer) with EdgeDB (EdgeQL is like GraphQL but with capabilities of SQL, and the DB itself has authn+authz baked-in).

Kabootit
0 replies
4h36m

Agree! Came here to give props to EdgeDB. Completely removes the API layer if used with something like SvelteKit. Everything defined in their schema language which then generates typed clients for you.

In my experience the use case is not limited to a single full-stack developer - this approach has turned our entire polyglot team into full-stack devs — no one is afraid of the data layer now. Super refreshing.

For public facing endpoints, "exposing an OpenAPI 3.0+ compliant JSON REST API" would be the first thing I'd reach for.

david_draco
1 replies
11h12m

There was a very short window of time when you could make very advanced queries over your Facebook friends graph. It was awesome.

cqqxo4zV46cp
1 replies
10h57m

So, TL;DR: if you want to exploit the flexibility offered by GraphQL, you need to pay for that with implantation complexity. I’ve never used GraphQL in my life yet can foresee the issues described in this post. If you try to retrofit GraphQL feature X, Y, or Z into your REST API, you’ll run into these exact same problems. If you stick with a classic REST API, you pay for that simplicity in other ways. Who here is on team “I have a plethora of use-specific endpoints”, and who here is on team “I built dynamic field selection and relationship traversal into API framework”? And, yeah. Dealing with N+1 database queries is loads easier if you constrain the potential pathways to the point that you can just hard-code your database optimisations instead of having to build a dynamic query optimiser. So you end up with a bunch of basic resource-mirror endpoints and then the N+1 database queries become N+1 HTTP requests. But hey, at least the requests are roughly equally expensive so you can simplify your rate limiting! As usual, it’s a question of trade offs, and it’s not the easy-path “you aren’t Facebook, so you don’t need it!” that people throw around here on the reg’. And, certainly, those that look down their nose and say “I know that I was right to not care for this, bloody magpie developers and their shiny toys” are certainly speaking with a misplaced sense of superiority.

dventimi
0 replies
7h18m

Not necessarily. Tools like Hasura, PostGraphile, and Prisma let you skip out without even having to pay with implementation complexity.

awirick
1 replies
6h7m

I've run into all of these issues running a GraphQL API and, while they aren't easy, they aren't exactly intractable either. Let's not pretend that OpenAPI/REST or Protobuf are perfect alternatives. They've each got their warts and tradeoffs.

The thing that I still _like_ about GraphQL is that it's a nice approach for expressing complex domain models over a protocol. If you are working with either REST or protos, you may still have to reason about graph-like structures but without the benefit of a graph-like schema.

hot_gril
0 replies
5h47m

OpenAPI can do graphs too, since you can put in refs to objects that can themselves have refs to other objects, possibly recursively.

adeptima
1 replies
6h20m

Back in 2021, I asked one of our devs who badly wanted GraphQL for his resume (this dev left in 6 months) to address the following issues:

- GraphQL performance issues

- GraphQL makes tasks more complex

- GraphQL schemas confuse junior devs, higher entry level

- REST cache easier

- REST if you understand what you are doing ... can do the same

- REST is better for error handling and tooling

Now in 2024, I clearly see LLMs gives much better autocomplete for REST or SDK code generated with protobuf ecosystem

There is not enough code repos based on GraphQL for LLMs to reason.

If you have like minded people who loves GraphQL, nothing can stop them but at higher and broader level it's a huge risk for dev velocity (like anything else if you dont know what you are doing)

merrywhether
0 replies
5h37m

Given that GraphQL makes much more sense for big orgs, I wouldn’t be surprised if much of that code is locked up in private repos that LLMs can’t get to.

PurpleRamen
1 replies
8m

Tab Grouping, Vertical Tabs, and our handy Sidebar will help you stay organized no matter how many tabs you have open — whether it’s 7 or 7,500.

Not sure if this will be good. This reads like they will add Vertical Tabs as a Sidebar, like all the other vertical tab-addons doing it now. But since the Quantum-update there is demand for a second sidebar dedicated for tabs, because as it's now, sidebar is really annoying to use.

But maybe it will at least add some improvements which the other addons can built upon.

More streamlined menus that reduce visual clutter and prioritize top user actions so you can get to the important things quicker.

Oh gosh, no! Why make them even worse than they are already now?

lbourdages
0 replies
5m

I think you replied to the wrong post :)

PaulHoule
1 replies
10h59m

When I saw GraphQL I immediately saw the issues that the poster talks about. I was amazed that people were drawn to it like a moth to a flame.

vvpan
0 replies
2h52m

I have used it on multiple projects and liked it, the project are still going strong a couple of years after and are maintainable.

Calamitous
1 replies
6h39m

Fundamentally, GraphQL is a _query language_, but people keep trying to build/use it as an _API_.

remus
0 replies
6h30m

The same thought struck me when reading the article. Imagine a world where your API was 'send me some SQL, return results' and you'd have the same problems as described.

vinnymac
0 replies
10h26m

I still enjoy using GraphQL, because it has allowed my teams to move measurably faster when developing APIs over the last half-decade. Some organizations seem fairly allergic to full stack development, but it has broken that barrier in ways I hadn’t witnessed before at my workplace.

However, lately I’ve been thinking that with the advent of React Server Components we will see a migration away from GraphQL-focused Frontend applications, and instead move toward other solutions. Such as ones based purely on exposing Postgres databases (e.g. supabase & postgREST) and type safe APIs (e.g. tRPC).

victor9000
0 replies
4h2m

My experience is that a stable graphql server is dependent on well behaved clients, which is not something you control.

victor106
0 replies
5h33m

This is a great post!!!

Not just for the content but I love it when someone changes their mind (very very hard thing to do) and details out what led them to change.

vendiddy
0 replies
7h7m

For something like OpenAPI+JSON REST API, does anyone have recommendations on tooling that would make my life easier?

I am also over GraphQL but I really like the api explorers, code completion, type safety, etc.

valenterry
0 replies
2h55m

For professional developers that know more or less what they are doing, most of those things are absolute non-issues. Let's list it:

if you expose a fully self documenting query API to all clients, you better be damn sure that every field is authorised against the current user appropriately to the context in which that field is being fetched.

The same is true for a "regular http API" [now abbreviated as "rest API"] (in case it's not clear: imagine how the http API would look like and think about if it would be somehow magically secure by default. Spoiler: it won't). Security by obscurity was never a great thing. It can help, but it's never sufficient on its own.

Compare this to the REST world where generally speaking you would authorise every endpoint, a far smaller task.

Just think about how many endpoints you would actually need to cover all combinations that the graphql API offers.

Rate limiting: With GraphQL we cannot assume that all requests are equally hard on the server. (...)

It's true. However: a rest API only makes that easier because it's less flexible and you have to manually create one endpoint for each of the various graphql API combinations. So instead, a classical graphql mitigation that the author does not mention is to simply require the client (or some clients) to only use fixed (predefined) queries. That is then the same as what a rest API does, problem solved. So graphql is not worse of here, but it can be much better.

Query parsing

This point is actually fair, except for the claim that there is no equivalent in REST. That is simply not true, as there have been many cases where rest frameworks worked with json and could be ddos'd by using large json numbers.

Performance: When it comes to performance in GraphQL people often talk about it’s incompatibility with HTTP caching. For me personally, this has not been an issue.

Funny, because that is indeed one factual disadvantage of graphql.

Data fetching and the N+1 problem: TLDR: if a field resolver hits an external data source such as a DB or HTTP API, and it is nested in a list containing N items, it will do those calls N times.

No, this is wrong. But first: this problem exists in a rest API as well, but worse: instead of N+1 queries to the DB, it will N+1 http requests AND N+1 db requests. But with graphql and some libraries (or some handwritten code) it is comparibly easy to write resolvers that are smart and "gather" all requests on the same query level and then execute them in one go. This is harder to do in a http api because you definitely have to do this by hand (as the auther describes).

GraphQL discourages breaking changes and provides no tools to deal with them.

What? Comon. In a rest API there is no means to do anything against breaking changes by default. Graphql at least comes with builtin deprecation (but not versioning though).

Reliance on HTTP response codes turns up everywhere in tooling, so dealing with the fact that 200 can mean everything from everything is Ok through to everything is down can be quite annoying.

True, but that can be adjusted. I did that and made it so that if all queries failed due to a user-error, the request will return 400, otherwise 204 if they partly failed.

Fetching all your data in one query in the HTTP 2+ age is often not beneficial to response time, in fact it will worsen it if your server is not parallelised

Okay, I'm starting to be snarky now: maybe choose a better language or server then, don't blame it on graphql.

And actually, many real problems of graphql don't even get mentioned. For example: graphql has no builtin map type, which is very annoying. Or, it has union types in the response, but you can't use the same types as inputs due to a lack of tagging-concept.

And so on. My conclusion: the auther is actually fairly inexperienced when it comes to graphql and they probably had a bad experience partly due to using ruby.

My own judgement: graphql is great except for very very specific cases, especially in projects that require huge amounts of servers and have a high level of stability in the API. I would always default to graphql unless the requirements speak against it.

unsupp0rted
0 replies
9h5m

Skill issue in my case, but I kept fighting against the caching of whatever GraphQL library I was using.

Made the dev experience a nightmare because I could never be sure whether it was my code or the client cache or the (actively in beta) server that was causing me to get back wrong data.

unnouinceput
0 replies
4h18m

I worked with CORBA during 90's and early 2000's. A truly shitty piece of technology that I do not wish upon my worst enemies, except maybe the higher ups at Microsoft who invented COM interfaces. When I saw the hype of GraphQL in 2017 I looked into it and while exploring it I started to have PTSD from CORBA days. "So you're the new CORBA, huh? I'll fuck off as far away as I can from you then" - and told the same to every client that even mention it.

tarkin2
0 replies
10h31m

I heard the argument that it's good because you don't need the server devs to change the backend; you can specify the data you want. As echo'd before, I guess that's great if your frontend and backend can't be developed in sync. Overall, I'd rather improve the development synchronisation/modification problem between backend and frontend than drive the GraphQL tank through the codebase. I guess I'll need to wait another 6 years before I can avoid GraphQL. Marketing-driven fads: exciting at the start of my career, a painful chore now

stratigos
0 replies
6h12m

The hype train strikes yet again! In fellow consultancy circles, we were giving talks on exactly this back in '17 and '18, but the hype train was too strong then. It was even harder to convince this same crowd that SPAs are usually a bad idea, and emerging technology like Hotwire or LiveView would soon eclipse the SPA-obsessed culture. GraphQL is immensely powerful and useful for its exact use case, and extremely burdensome and expensive for any other use case. If you dont already know that use case, YAGNI. The same can be said for any hype train. The problem with any kind of hype train in tech is everyone looks for reasons to use whatever the new hyped thing is, rarely does anyone determine if the new hyped thing actually fits their use case(s). This will continue so long as there is a dichotomy of culture between youths and those with lengthy experience. We old people will continue to point out exactly why this or that is pure hype, and will continue to be drowned out by the emotions that come along with participating in hype.

smrtinsert
0 replies
5h13m

Graphql via spring is easy integrates seamlessly. Obviously stick to its core use cases and it will go great.

shudza
0 replies
9h14m

If only developers/managers had their own sense of using the proper tools for the job instead of just swallowing everything the Big Tech shoves down their throat...

But when you see those job ads with all these "great new technologies" it's hard not to fall into the trap.

santoshalper
0 replies
1h8m

Of all the dumb ideas in the history of engineering, exposing an access point for strangers to query your database is certainly one of them. I cannot imagine that anyone involved had experience running enterprise systems at scale.

rootedbox
0 replies
1h18m

GraphQL.. when people didn't learn their lessons from SOAP..

rbalicki
0 replies
2h5m

Folks on this thread should check out Isograph: https://isograph.dev and https://www.youtube.com/watch?v=gO65JJRqjuc.

GraphQL has a lot of advantages, the most important of which is data masking. In a properly structured GraphQL app, only the function that requested a field (i.e. included it in a fragment) sees that field. This allows many developers to move independently, without communication or coordination.

It's unfortunate, but there are lots of rough edges with GraphQL and it is hard to incrementally adopt, and so if you don't have enough developers (to have communication issues) and a team devoted to adoption, it might not be worth it.

Anyway, Isograph is a framework that seeks to take away many of those rough edges, while baking in stuff like data masking, etc. Y'all should check it out!

rambojohnson
0 replies
5h11m

yes, let's conflate bad API / schema design with GraphQL / the technology being the problem.

quonn
0 replies
10h54m

GraphQL is a great choice for internal applications hidden behind strong authentication that do not need to be heavily cached and where things like DoS are less of a concern or no concern at all.

It is often a poor choice for websites that should be cached, are publicly accessible and have simple and predictable data access patterns.

GraphQL has a fairly flat but very long learning curve which makes it a power tool that is great for those who have learned it in depth. Without that experience one is almost always better off using REST.

qaq
0 replies
28m

One context it works well in is something like PostGraphile. You basically spend very little time developing the back end. This obviously does not scale to very large projects.

presentation
0 replies
6h59m

I’ve found success just using GraphQL internally (with tools like Hasura or Postgraphile + row level security done strategically) and not exposing it directly externally. That way you can trust the clients and it unblocks frontend devs to accomplish what they need.

phaedryx
0 replies
4h52m

I worked on a GraphQL API a few years ago and we solved these problems at the beginning and then forgot about them. We generated the schema for a user from their CanCan abilities (CanCan can handle attribute-level access, I wrote the PR). Shopify has support gems for the N+1 stuff, if I remember correctly. You can limit how many levels deep your query can go. We added some rate limiting.

Basically, these are all solved problems.

petesergeant
0 replies
6h33m

What are people using these days for TypeScript on both ends? I have a home-grown solution that starts with Zod schemas and gives synchronized types on the front end and backend as well as a client for free, but I'm always interested in using something standard

patricius
0 replies
3h33m

I will, once again, bring your attention to hashql, which is so pleasant to use. It's so minimal that it is almost more a pattern than a library. Try it out as an alternative to graphql if you are mainly querying a SQL database anyhow (although it can be easily configured to request data from other types of sources.) I don't think it can currently combine results from multiple data sources, but I think it should be within the realm of possible things

https://github.com/porsager/HashQL

oreoftw
0 replies
10h7m

Exposing bare GraphQL the right way can be challenging, totally agree with author on that. Using it on a small project also can be an overkill.

But at the same time it doesn’t have to be that bad. I don’t have this array of issues because I do: - query whitelisting for performance and security, - data loading to avoid n+1, authentication with whatever works(session cookies, tokens), - permission check based on the auth context in a resolver.

It works decently for us, allowing to stay away from getting into ESB. Yet have some shared domain, type safety, and easy integration of legacy and new systems/services.

I would say a bigger issue for us was to keep it all nicely organized / designed in terms of types and api contracts. But that’s manageable.

oksteven
0 replies
12h6m

GraphQL was the shiny new thing that everyone was excited about and I was also trying to learn and use it too, but I've never found a compelling use-case to use it over REST API. Now that you shared your experiences with it, it give me more reason to stay away from it. Plus, I think it's more productive to stay with the stack I'm very fluent at.

nojvek
0 replies
3h48m

REST is simple and works well with debuggers, logging, caching, auth, request throttling e.t.c

For graphql like needs we use a standard set of props (select, filter, sortBy, limit, offset).

They map to a single sql statement and executed efficiently by PG.

select can be nested properties if we need deeper nesting. Server emits typescript types package for frontend.

It's worked really well so far at our scale. Eng team is fairly productive.

nailer
0 replies
1h23m

Your most precious resource is time. I'm really glad of the time I invested in Python, node, TypeScript, Virtualisation and Serverless.

I'm less happy about the time I wasted on bash, DOOM WADs, and Desktop Linux. Yes these are are all a while ago. I didn't invest my time wisely when I was young.

I'm also glad I didn't invest in GraphQL, Kubernetes, Angular, Solaris, and perl.

mocamoca
0 replies
1h5m

If someone from Shopify's backend team is around, i would love to know how difficult it is to maintain/improve the GraphQL API It looks like Shopify is deprecating REST in favor of GraphQl so is the developer UX that good for Shopify developers? And btw some features are missing from the GraphQL related to REST. I wonder if that's related to hard-to-implement features or good-occasion-to-delete features (Eg Checkout)

mbleigh
0 replies
5h37m

TL;DR GraphQL isn't really the problem, untrusted clients executing arbitrarily complex queries is the problem. This is why authz is hard, why rate-limiting is necessary, why "query complexity" calculations are necessary...

At Firebase we chose GraphQL as the basis for our new Data Connect PostgreSQL product (https://firebase.google.com/products-data-connect) despite acknowledging pretty much all of the issues outlined in this article as correct.

GraphQL is an excellent IDL (interface definition language). It's compact, it's flexible (through directives), and there's literally no better way I'm aware of to rapidly construct complex nested relational queries. But the promise of "clients can fetch whatever they want" adds an enormous burden to backend developers because you have to secure yourself against queries of arbitrary shape and complexity.

In reality you don't want clients to "fetch whatever they want" because clients can't be trusted. The path we took is that developers can predefine the queries that are needed for their client, and then only those queries can be executed from an untrusted client.

This approach provides a surprising number of benefits - you get the flexibility of nested queries and field selection, the end-to-end strongly typed structure of a schema-driven API, and the ability to reason about security like it's a custom backend.

mannyv
0 replies
6h32m

From a backend point of view, you will never be able to stop front end people from doing the wrong thing with an API.

GraphQL makes it easier for front-end developers to do the wrong thing, which is why they love it.

ksec
0 replies
7h47m

GraphQL is an incredible piece of technology that has captured a lot of mindshare since I first started slinging it in production in 2018.

6 years. For a lot of people, that was also the time ( 2013 - 2019 ) they moved from SPA or Client Side Rendering and started looking or move back to HTML+ approach.

So may be for any company operating on Boring Technology principle, you should not choose any hyped tech until they have been battle tested by the market for 7 years.

kabes
0 replies
1h10m

Except, the alternatives he presents aren't alternatives.

And for each issue he mentions that rest doesn't have said issue is basically because rest doesn't have the feature at all.

You could use graphql the same way as rest (by exposing queries without allowing to specify fields) and you still have a better rest, since at least the response has a schema out of the box.

jupp0r
0 replies
3h40m

95% of this is specific to Ruby, not GraphQL. I also found ruby-graphql not to be a excellent library in contrast to what the author says. Other implementations (apollo for node, gqlgen for Go) alleviate many of the concerns mentioned in the article, especially when implementing the server with certain principles in mind (always use the data loader pattern, etc).

icar
0 replies
9h14m

At work we also stopped using Graphql and we only have a few endpoints left to migrate in our internal dashboard. Nobody that has worked on this project has liked the dx.

iamyemeth
0 replies
3h37m

Why, after 6 years, I'm over increased complexity for marginal benefit. Sounds like most things developed and promoted by FANG

hot_gril
0 replies
5h53m

I started at the same conclusion of using OpenAPI and never ventured into GraphQL cause I only had one client.

hansonkd
0 replies
7h46m

I never understood peoples positions that GraphQL all of the sudden the frontend can make any Query it wants and control is out of the hands of the backend. That seems orthogonal to my experiences with GraphQL.

GraphQL is a protocol and you define the implementation. Some GraphQL implementations like REST implementations try to generate everything for you. That is not "GraphQL" but one type.

GraphQL is way to query nested APIS. The dataloading N+1 Problems are substantially easier to solve in GraphQL and many frameworks have solutions auto-optimize ORM queries for example.

The backend defines the query, the frontend requests it. Simple. Never understood the hate against GQL that now the frontend has all this power. They have exactly as much power as you would have exposed in a Rest Interface just now the backend can actually see all the data it needs at once and optimize.

If you are worried about a cartesian product from a GraphQL call I have news for you about production REST systems. Ever seen an engineer do a loop and make n+1 REST calls for resources? It happens more often then you think.

REST encourages resource waste. You are getting fields you don't need. Hard to query related objects, etc.

Benefits I have reaped with GraphQL:

  1. API analysis - I can statically analyze a typescript program and verify their API calls are valid against backend schema.
  2. Usage analysis - Statically analyzing the schema I can see which fields are still in use and safely refactor.
  3. Frontend Velocity - The frontend can cange its data needs on the frontend query whatever related objects it needs efficiently without backend changes. You can get all data for a page with 1 call and not have to have page specific endpoints.
  4. Less backend engineers are needed as API changes less.
  5. N+1 Optimization much easier to solve in GraphQL then REST
There are so many advantages to using GraphQL. The only advantage of REST I can think of is for static external APIs.

hakanderyal
0 replies
10h11m

Full blown GraphQL is hard to properly support. It needs a lot of developer time to get everything correct, as stated in the article.

However, you can go very far with a simpler version of it, just by allowing clients to specify what fields/relations they want and in what context.

I'm using a library that I've created for myself for years without any of the problems mentioned in the article.

The client side queries are generated by the server at compile time. Each request for an object requires a "segment" to be specified. On the server, each segment has the necessary filters/limits automatically applied to prevent data leaks.

greens231
0 replies
7h23m

shameless plug: i have been working on https://querydeck.io/ as a side project to bring the ease of use of graphql to REST apis. the plan is to open source it later in the year once its out of beta

graemep
0 replies
11h12m

I would have thought all of those were fairly obvious. It is more complex and gives the client a lot more power and control, so the trade-off is inevitable.

garydevenay
0 replies
2h5m

I admire the 6 year dedication (or architectural investment?). We were both jumping aboard that hype train in 2018, even talked about it in meat-space. I left that project in 2019 and never looked at GraphQL again, so didn’t make it as far you to the technical depths.

Something just never felt right about the client building the queries for me, I guess.

frabjoused
0 replies
3h47m

For some reason every person I have worked with that pushed GraphQL seemed sufficiently obsessed with the idea of it that they prioritized its perceived elegance over the product we were trying to build.

In other words, they cared more about ideal ways to access data than the product of that data.

This has so consistently been the case in my personal experiences that I avoid people in hiring interviews that start talking about or try to sell me on why I should switch my stack to GraphQL.

finack
0 replies
5h54m

Well yeah, who knew that letting your frontend developers blow up your database because nobody talks to each other or designs things anymore would be a bad idea?

eterps
0 replies
10h30m

    > Data fetching and the N+1 problem
    > [...] if a field resolver hits an external data source such as a DB or HTTP API, and
    > it is nested in a list containing N items, it will do those calls N times
Why is this considered a problem regardless of the situation at hand?

F.e. using REST, if the nested list contains on average N-2 items that can be efficiently cached, wouldn't that be better than having the cache constantly invalidated on the aggregation of the parent and its items?

emorning3
0 replies
5h56m

Odata is 80% of GraphQL with only 20% of the hassle.

electrondood
0 replies
6h11m

GraphQL is a great way for FE devs to make life harder for BE devs.

The entire point is composition + client customization of the response body, but in practice the request schema is never modified. And even if it were, you could just version a REST endpoint.

GraphQL is never done "correctly," adds a layer of obscurity to monitoring and error tracing, and I've yet to see a case where it's actually the right tool for the job.

Maybe if you need to aggregate calls to multiple services into one, but if you're trying to avoid latency by reducing number of calls, you still eat that latency while the GraphQL server makes those calls for you.

GraphQL sucks.

edude03
0 replies
5h10m

Despite all of these things ringing true for me as well at the last few companies/projects I worked at that used graphql, I will say that like everything in tech, there are trade offs, but if the tool generally solves the problem you have well, you'll be motivated to find solutions to the additional problems you have - which often means the argument actually comes down to who is more passionate about the particular tech.

One example that stood out to me though:

GraphQL discourages breaking changes and provides no tools to deal with them.

GraphQL the standard doesn't provide tools no, but I've been very successful using Apollo Studio to solve this as (in my experience) the workflow maps to how you generally develop applications:

1) agree on some schema 2) make a (Apollo studio) "branch" with the schema change 3) mobile & backend devs (typically) code gen the objects they need for the schema 4) backend dev deploys a preview branch of their implementation, mobile dev points the client to it 5) test it, merge it, publish the schema on the main "branch" - deal with the breaking changes if Apollo warns you of them.

So maybe you can accomplish this with other tools, and maybe it's not fair to compare "the standard" to a particular tool, but I usually say I stick to gql (where appropriate) because there is a tool for it that works so well for the problem(s) I'm typically solving.

dudeinjapan
0 replies
10h46m

I was over GraphQL the moment I looked at the specification.

donatj
0 replies
11h8m

For the service I primarily work on, we've stuck firmly with REST for our internal APIs despite some mild pressure from elsewhere in the company to move to GraphQL. I personally believe it's been the right choice. Not only would it be probably an order of magnitude more complicated to setup and maintain, our REST APIs already are very performant.

We've got little to gain, and the lack of flexibility from our POV is a relatively good thing. It gives us direct insight into desired use cases, and since the APIs are internal it lets us provide guidance on potentially better ways of implementing things as well as in some cases being able to provide direct optimizations for specific tasks.

deadbabe
0 replies
6h25m

The consensus I get from these comments is GraphQL is ultimately a failure as a REST API alternative. It’s useful for very specific cases that most companies don’t have.

dcre
0 replies
8h26m

“the main thing your frontend devs like about GraphQL is its self documenting type safe nature”

I’ve been saying this for years: fetching multiple things in one query is not something normal-scale apps care about. What devs like about it is client generation and type safety. So OpenAPI, for all its flaws, covers that. GraphQL’s schema language is much more beautiful — hopefully Microsoft’s TypeSpec will take off and we can have the best of both worlds.

https://typespec.io/

Another point implicit in the piece but not quite stated is that GraphQL aims to make something nice for the API consumer, but the implementation side is a nightmare. It is not worth the tradeoff because eventually, that nightmare leaks out to the consumer because it is too hard to make improvements to the API.

davidw
0 replies
4h14m

I used it at a past place (didn't choose it) and IDK, it just seemed like one more layer that wasn't really buying us much. Wasn't a fan.

dartos
0 replies
8h2m

Has anyone use graphql for service to service communication?

Seems really great to not have each service adhere to another service’s potentially unstable api contract.

Especially if that service is owned by another team.

combiBean
0 replies
9h52m

I think the post is definitely mentioning a few valid points which need to be addressed in proper GraphQL API designs. But most of REST "solutions" over GraphQL considerations are just pushing issues from the server side to the client side.

For example the whole n+1 data fetching topic: Yes this issue exists and like the author is mentioning: GraphQL has a well understood and common solution for this problem. On the other hand: In REST world you can have exactly the same issue, but either create a custom solution for this issue or push the issue to the client side, where this issue needs to be solved, too. I could not exactly follow the explanation of the special case of the n+1 problem in context of authorization. "This is actually trickier [...], because authorisation code is not alway run in a GraphQL context." OK authorisation code is not run in a GraphQL context, but why is this then a GraphQL issue?

On the rate limiting issue I also do not see why these issue would by design just exist in GraphQL world: Yes you can have recursive data structures and write queries which can take a lot a processing time to resolve. But again: Why would the same recursive data structure not be possible to be modeled for a rest api and why would the same data not be queriable from a rest api? My guess again is: You _can_ model the same data structure and also _can_ query the same amount of data. And also again: In case of the rest api the complexity of querying this data is just pushed to the client side and that is why it seems easier to rate limit individual rest endpoints. But actually I see no reason why a GraphQL API could not rate limit e.g. on data loader or any expensive operation level, too.

Generally regarding malicious (e.g. malformed) queries: I think this is definitely a valid issue, which should be addressed in GraphQL APIs. I think there should be a common way for application developers to sign their queries somehow and query engines should only attempt to process signed queries. This way only trusted developers are able to write arbitrary queries.

On the "Authorisation" section I can not quite follow the reasoning. Aside from implementation-specific extra-calls to a presumed authorisation framework: Why would domain requirements be different when they are implemented either as REST API or as a GraphQL API?

"Compare this to the REST world where [...] you would authorise every endpoint". OK if you can implement an authorization requirement simply on a REST endpoint, why could you not implement this simply on a Query-Type field in an equivalent GraphQL API? If this is about authorization on nested data structures: Can you not have equally nested data structures on REST endpoints, too? I think in these cases authorization on REST endpoints wouldn't be sufficient, too. Assuming you would avoid nested data structures: Would this not simply push the n+1 problem from the server side to the client side?

My general feeling about the REST vs GraphQL debate is both worlds can in principal cause pretty much the same issues. Even for client side caching I see no real design issue which prevents GraphQL queries and responses to be cached, but probably more like a middleware issue. On the other hand I still see a lot of benefit in using GraphQL: Especially the query flexibility for developers, the solved the n+1 query problem (which may still exists on the rest client side or is solved by a custom solution) and the error handling. I still hate to define exact use of HTTP status codes and custom error payload structure in every context where REST is a new or badly defined concept again and again.

casperb
0 replies
7h18m

I like restful API’s the most. Graphql is cool if you need data combined that is not nicely available in the restful endpoints. But I think that could mostly be solved with good endpoints that help with the actual use cases. When restful endpoints are hard to use, in a lot of cases it is because they are to much focused on how it is easy to write server side, then it is to consume them.

bluehatbrit
0 replies
10h26m

I've had the "pleasure" (/s) of inheriting a pretty large GraphQL API which I've had to maintain for the past few years. I've gone through the process of the hype, and then the sheer frustration. I'm now at the point where I think most people are just using it in the wrong places.

GraphQL works pretty well when it's acting as a Backend-For-Frontend. The client can make a single call to get everything it needs at once, the BFF can then fan out to various microservices as needed. The frustrating part is when it's blindly used for something like a monolithic CRUD API with some light permissions. In that scenario you're taking all of the drawbacks, without reaping any of the benefits.

I'm really glad to be leaving this project behind as I move jobs, and I'm praying no one suggests using it in my new job. At least not until the industry more broadly understands it in more depth.

bilater
0 replies
4h27m

I never understand how people end up needing overly complex queries (REST or GRAPHQL). Maybe it's harder to coordinate in bigger orgs but I have almost always found its better to go to the DB, create some logic there like a new table or sql view and do a simple query from the client. It keeps thing way more performant and simple.

anonzzzies
0 replies
10h26m

Ah, this is the advantage I have waiting at least 10 years of everyone I care about whining I need to use a technology. I had a few years of people telling me about graphql and how it is the best etc, but they stopped after a bit and are doing rest endpoints again. So I never tried it even.

andy_ppp
0 replies
33m

Using Elixir+Absinthe solves most of these problems and the idea that a non-self documenting API doesn’t need every field to be secure is quite frankly a ridiculous thing to label as a problem for GraphQL, maybe the self documentation encourages better security practices, who knows!?

__loam
0 replies
10h24m

Graphql was routinely an overly complex piece of shit when I was forced to deploy software with it.

SJC_Hacker
0 replies
4h38m

I never understood the problem that GraphQL was trying to solve. If REST doesn't work for you, I don't see what was wrong with query strings, or JSON parameters.

Ozzie_osman
0 replies
6h7m

As an alternative datapoint, we use GraphQL for a medium-sized app, are several years in, and are pretty happy with it. The downsides he mentions are all true, but on the other hand, are addressable, and for us feel worth the benefits of getting flexibility and control on the client-side.

GenCuriosity
0 replies
9m

And with spec first and OpenAPI Spec we are back to the methods and tools, that we hadwith WSDL/XSD and SOAP/XML like 20 years ago. We went full circle. :) I love IT

The problems with GraphQL where so obivious in the first 5 minutes that I looked into that. Looks smart and flexible - but isn't

CharlieDigital
0 replies
10h19m

My $0.02 here:

GraphQL makes sense only at a certain scale when you have multiple APIs built by multiple teams that need to be exposed as a single endpoint. GraphQL as an API or APIs is the perfect use case and the one that it was designed for.

In every other case, REST is harder to do wrong and easier to do right. The tooling for it is widely supported and well known. Every aspect of building an easy to use, easy to own, easy to scale API is -- well -- just easier with REST.

I have seen more than a few small, 4-8 person engineering teams reach for GraphQL and then wonder why every cycle starts feeling slow. In a 4-8 person team, the devs are usually working full stack and if not, then they are working closely enough that having a highly flexible API layer servicing the front-end doesn't make any sense since it's either the same devs or they're one Slack ping away from getting the right shape from the backend in one simple `GET`.

Like the author, I've found that the story with OpenAPI nowadays is really good. I have a short writeup here with .NET that shows hot re-generation of the API into a TypeScript definition that can be used with React, Vue, or your framework of choice: https://chrlschn.dev/blog/2023/10/end-to-end-type-safety-wit...

This workflow is super productive and perfect for small teams working full stack; far easier than getting GQL right.

6510
0 replies
9h29m

I post sql queries to my backend then match them against the exact string. The lack of flexibility is on purpose.