[HN Gopher] GraphQL: The enterprise honeymoon is over
___________________________________________________________________
GraphQL: The enterprise honeymoon is over
Author : johnjames4214
Score : 63 points
Date : 2025-12-14 17:13 UTC (2 hours ago)
(HTM) web link (johnjames.blog)
(TXT) w3m dump (johnjames.blog)
| gideon60 wrote:
| Yup, honeymoon is over. Now is the time for the adult, long-term,
| and productive relationship.
| sibeliuss wrote:
| Exactly! Once its working, it can be very healthy. And
| especially on the client. For a very, very, very long time. We
| started using GraphQL at the very beginning, back in 2015, and
| the way it has scaled over time -- across backend and frontend
| -- has worked amazingly well. Going on 10 years now and no
| slowing down.
| c-hendricks wrote:
| We haven't been using it as long but it's definitely saved us
| from things that were "impossible" to associate in our
| microservice backend.
| fcpguru wrote:
| i wrote this a few weeks ago:
|
| https://gist.github.com/andrewarrow/c75c7a3fedda9abb8fd1af14...
|
| 400 lines of QL vs one rest DELETE / endpoint
| gideon60 wrote:
| Feels like a schema design issue? If your REST backend exposes
| a single path to remove an item, are there any reason why your
| GraphQL schema doesn't expose a root mutation field taking the
| same arguments?
| fcpguru wrote:
| yeah tell shopify, it's their api!
| johnjames4214 wrote:
| Exactly. If it's that verbose and painful for a public API
| like Shopify/GitHub (where the 'flexibility' argument is
| strongest), it makes even less sense for internal
| enterprise apps.
|
| We are paying that same complexity tax you described, but
| without the benefit of needing to support thousands of
| unknown 3rd-party developers.
| n_e wrote:
| The issue is that the API itself is, I assume, badly
| designed.
|
| Equivalent delete queries in rest / graphql would be
| curl -X DELETE 'https://api.example.com/users/123'
|
| vs curl
| 'https://api.example.com/graphql?query={ deleteUser(id:
| 123) { id } }'
| throwaway613745 wrote:
| wut
|
| we have a mixed graphql/REST api at $DAY_JOB and our delete
| mutations look almost identical to our REST DELETE endpoints.
|
| TFA complains needing to define types (lol), but if you're
| doing REST endpoints you should be writing some kind of API
| specification for it (swagger?). So ultimately there isn't much
| of a difference. However, having your types directly on your
| schema is nicer than just bolting on a fragile openapi spec
| that will quickly become outdated when a dev forgets to update
| it when a parameter is added/removed/changed.
| websiteapi wrote:
| I tried graphql with hasura and it was pretty neat, but it still
| just seemed easier to use RPC or REST.
| EionRobb wrote:
| The article pretty much sums up why I've been a bigger fan of
| OData than GraphQL, especially in the business cases. OData will
| still let you get all those same wins that GraphQL does but
| without a sql-ish query syntax, and sticking to the REST roots
| that the web works better with. Also helps that lots of Microsoft
| services work out of the box with OData.
| hn_throwaway_99 wrote:
| > The main problem GraphQL tries to solve is overfetching.
|
| My issue with this article is that, as someone who is a GraphQL
| fan, that is _far_ from what I see as its primary benefit, and so
| the rest of the article feels like a strawman to me.
|
| TBH I see the biggest benefits of GraphQL are that it (a) forces
| a _much_ tighter contract around endpoint and object definition
| with its type system, and (b) schema evolution is much easier
| than in other API tech.
|
| For the first point, the entire ecosystem _guarantees_ that when
| a server receives an input object, that object will conform to
| the type, and similarly, a client receiving a return object is
| guaranteed to conform to the endpoint response type. Coupled with
| custom scalar types (e.g. "phone number" types, "email address"
| types), this can eliminate a whole class of bugs and security
| issues. Yes, other API tech does something similar, but I find
| the guarantees are far less "guaranteed" and it's much easier to
| have errors slip through. Like GraphQL always prunes return
| objects to just the fields requested, which most other API tech
| _doesn 't_ do, and this can be a really nice security benefit.
|
| When it comes to schema evolution, I've found that adding new
| fields and deprecating old ones, and _especially_ that new
| clients only ever have to be concerned with the new fields, is a
| huge benefit. Again, other API tech _allows_ you to do something
| like this, but it 's much less standardized and requires a lot
| more work and cognitive load on both the server and client devs.
| hjnilsson wrote:
| Agree whole-heartedly. The strong contracts are the #1 reason
| to use GraphQL.
|
| The other one I would mention is the ability to very easily
| reuse resolvers in composition, and even federate them.
| Something that can be very clunky to get right in REST APIs.
| verdverm wrote:
| re:#1 Is there a meaningful difference between GraphQl and
| OpenAPI here?
|
| Composed resolvers are the headache for most and not seen as
| a net benefit, you can have proxied (federated) subsets of
| routes in REST, that ain't hard at all
| 8n4vidtmkvmk wrote:
| Pruning the request and even the response is pretty trivial
| with zod. I wouldn't onboard GQL for that alone.
|
| Not sure about the schema evolution part. Protobufs seem to
| work great for that.
| FootballMuse wrote:
| Pruning a response does nothing since everything still goes
| across the network
| hn_throwaway_99 wrote:
| You're misunderstanding. In GraphQL, the _server_ prunes
| the response object. That is, the resolver method can
| return a "fat" object, but only the object pruned down to
| just the requested fields is returned over the wire.
|
| It is an important security benefit, because one common
| attack vector is to see if you can trick a server method
| into returning additional privileged data (like detailed
| error responses).
| hn_throwaway_99 wrote:
| > Pruning the request and even the response is pretty trivial
| with zod.
|
| I agree with that, and when I'm in a "typescript only"
| ecosystem, I've switched to primarily using tRPC vs. GraphQL.
|
| Still, I think people tend to underestimate the value of
| having such clear contracts and guarantees that GraphQL
| _enforces_ (not to mention it 's whole ecosystem of tools),
| completely outside of any code you have to write. Yes, you
| can do your own zod validation, but in a large team as an API
| evolves and people come and go, having hard, unbreakable
| lines in the sand (vs. something you have to roll your own,
| or which is done by convention) is important IMO.
| dgan wrote:
| Sorry but not convinced. How is this different from two
| endpoints communicating through, lets say, protobuf? Both input
| and output will be (un)parsed only when conforming to the
| definition
| nisalperi wrote:
| My hot take is that if you're using GraphQL without Relay, you're
| probably not using it to its full potential. I've used both Relay
| and Apollo Client on production, and the difference is stark when
| the app grows!
| tonyhart7 wrote:
| I don't like GraphQL, it feels strange for me (for my rest brain)
|
| despite many Rest flaw that I know that it feels tedious
| sometimes, I still prefer that
|
| and now with AI that can scaffold most rest. the pain point of
| rest mostly "gone"
|
| now that people using a lot of Trpc, I wonder can we combine Grpc
| + rest that essentialy typesafe and client would be guaranteed to
| understand how model response look ?????
| pjmlp wrote:
| I wish, plenty of SaaS their main query API is GraphQL.
| trashymctrash wrote:
| What I liked about GraphQL was the fact that I only have to add a
| field in one place (where it belongs in the schema) and then any
| client can just query it. No more requests from Frontend
| developers like ,,Hey, can you also add that field to this
| endpoint? Then I don't have to make multiple requests". It just
| cuts that discussion short.
|
| I also really liked that you can create a snapshot of the whole
| schema for integration test purposes, which makes it very easy to
| detect breaking changes in the API, e.g. if a nullable field
| becomes not-nullable.
|
| But I also agree with lots of the points of the article. I guess
| I am just not super in love with REST. In my experience, REST
| APIs were often quite messy and inconsistent in comparison to
| GraphQL. But of course that's only anecdotal evidence.
| matsemann wrote:
| But the first point is also its demise. I have object A, and
| want to know something from a related object E. Since I can ask
| for A-B-C-D-E myself, I just do it, even though the performance
| or spaghettiness takes a hit. Then ends up with frontend that's
| tightly coupled to the representation at the time as well, when
| "in the context of A I also need to know E" could've been a
| specialized type hiding those details.
| gavinray wrote:
| I'm probably about as qualified to talk about GraphQL as anyone
| on the internet: I started using it in late 2016, back when
| Apollo was just an alternate client-side state/store library.
|
| The internet at large seems to have a fundamental
| misunderstanding about what GraphQL is/is not.
|
| Put simply: GQL is an RPC spec that is essentially implemented as
| a Dict/Key-Value Map on the server, of the form: "Action(Args) ->
| ResultType"
|
| In a REST API you might have app.GET("/user",
| getUser) app.POST("/user", createUser)
|
| In GraphQL, you have a "resolvers" map, like: {
| "getUser": getUser, "createUser": createUser, }
|
| And instead of sending a GET /user request, you send a GET /query
| with "getUser" as your server action.
|
| The arguments and output shape of your API routes are typed, like
| in OpenAPI/OData/gRPC.
|
| That's all GraphQL is.
| jayd16 wrote:
| This seems a bit reductive as it skims over the whole query
| resolution part entirely.
| verdverm wrote:
| Which is where the real complexity comes in
| thom wrote:
| This, for me, is a perfect description of the entirety of
| GraphQL tbh.
| ericyd wrote:
| Is this relevant to the posted article? I don't see how the OP
| misrepresents anything about GQL.
| 8n4vidtmkvmk wrote:
| I think you're oversimplifying it. You've left on the part
| where the client can specify which fields they want.
| verdverm wrote:
| That's something you should only really do in development,
| and then cement for production. Having open queries where an
| attacker can find interesting resolver interactions in
| production is asking for trouble
| exasperaited wrote:
| I dunno. I still really like Lighthouse (for Laravel).
|
| It's about the only thing about my job I still do like.
|
| The difference is that it is schema-first, so you are describing
| your API at a level that largely replaces backend-for-frontend
| stuff. If it's the only interface to your data you have a lot
| less code to write, and it interfaces beautifully with the query
| builder.
|
| I tend not to use it in unsecured contexts and I don't know if I
| would bother with GraphQL more generally, though WP-GraphQL has
| its advantages.
| storafrid wrote:
| A blog post about GraphQL in an enterprise setting, that fails to
| address the biggest GQL feature for enterprises. Not unlike most
| material on HN about microservices. Federated supergraph is the
| killer feature imo.
| ericyd wrote:
| The author states that in their experience, most downstream
| services are REST, so adding a GQL aggregation layer on top
| isn't very helpful. It seems possible they would have a
| different opinion if they were working with multiple services
| that all implemented GQL schemas.
| FootballMuse wrote:
| Being able to federate REST alongside GQL has been a value
| add in my experience. Apollo even has the ability to do this
| client side
| wrs wrote:
| In that (common) case, the advantage is the frontend/app
| developers don't need to know what a hot mess of inconsistent
| legacy REST endpoints the backend is made of, only the GQL
| layer does. Which also gives you some breathing room to start
| fixing said mess.
| timcobb wrote:
| > The main problem GraphQL tries to solve is overfetching.
|
| this gets repeated over and over again, but if this your take on
| GraphQL you def shouldn't be using GraphQL, because overfetching
| is never such a big problem that would warrant using GraphQL.
|
| In my mind, the main problem GraphQL tries to solve is the same
| "impedance mismatch" that ORMs try to solve. ORM's do this at the
| data level fetching level in the BE, while GraphQL does this in
| the client.
|
| I also believe that using GraphQL without a compiler like Relay
| or some query/schema generation tooling is an anti-pattern. If
| you're not going to use a compiler/query generation tool, you
| probably won't get much out of GraphQL either.
|
| In my opinion, GraphQL tooling never panned out enough to make
| GraphQL worthwhile. Hasura is very cool, but on the client side,
| there's not much going on... and now with AI programming you can
| just have your data layers generated bespoke for every
| application, so there's really no point to GraphQL anymore.
| verdverm wrote:
| I have strong agreement here and would add reasoning about auth
| flow through nested resolvers is one of the biggest challenges
| because it adds so much mental overhead. The reason is that a
| resolver may be called through completely different contexts and
| you have to account for that
|
| The complexity and time lost to thinking is just not worth it,
| especially once you ship your GarphQL app to production, you are
| locking down the request fields anyway (or you're keeping
| yourself open for more pain)
|
| I even wrote a zero-dependency auth helpers package and that was
| not enough for me to keep at it
|
| https://github.com/verdverm/graphql-autharoo
|
| Like OP says, pretty much everything GraphQL can do, you can do
| better without GraphQL
| mohas wrote:
| using graphql specifically Apollo was one of my regrettable
| decisions when I was designing a system 3 years ago, one that
| haunts me still today with wired bugs, too much effort to upgrade
| the version while prev version still have bugs etc. and I lost
| performance and simplicity of rest on top of that
| ramon156 wrote:
| I like that Shopify chose GraphQL and I believe their API
| would've been messier if they kept the REST endpoint.
|
| Maybe I'm missing something, but I think they did well
| adsharma wrote:
| It's interesting to see people use the term "GQL" to refer to
| GraphQL.
|
| https://www.gqlstandards.org/ is an ISO standard. The Graph
| Database people don't love search engine results when they're
| looking for something.
|
| I maintain a graph database where support for GQL often comes up.
|
| https://github.com/LadybugDB/ladybug/issues/6
| jayd16 wrote:
| One interesting conjecture that GQL makes, I think, is that
| idempotent request caching at the http level is dead... Or at
| least can't be a load bearing assumption because the downstream
| can change their query to fetch differently.
|
| Do we think this has turned out to hold? Is caching an API http
| response of no value in 2025.
| be_erik wrote:
| The appeal of GraphQL is that it eliminates the need for a BFF
| and easily solves service meshing. Over fetching is more of a
| component design problem than a performance issue.
| aabhay wrote:
| How do GraphQL based systems solve the problem of underlying
| database thrashing, hot shards, ballooning inner joins, and other
| standard database issues? What prevents a client from writing
| some adversarial-level cursed query that causes massive internal
| state buildup?
|
| I'm not a database neckbeard but I've always been confused how
| GraphQL doesn't require throwing all systems knowledge about
| databases out the window
| delichon wrote:
| E.g. graphql-ruby supports filtering out queries by depth, or
| node count, and you can write custom complexity filters. You
| also have full control over the resolvers, and it's often easy
| to filter out the tough stuff. There's also a fair amount of
| control implicit in controlling the schema, you just skip
| creating the most costly associations, or forbid a swath of
| them in the resolver.
|
| For a lot of systems, you really aren't required to support any
| arbitrary query. Our GraphQL implementation was only used
| internally, so we were ready to whitelist the queries used by
| our internal apps, but that wasn't needed.
|
| One effective strategy was just using timeouts. The server
| tells consumers that last query was too hard, and if they test
| it right they discover that before production.
| spooneybarger wrote:
| Most servers implement a heuristic for "query cost/complexity"
| with a configurable max. At the time the query is parsed, its
| cost is determined based on the heuristic and if it is over the
| max, the query is rejected.
| ianberdin wrote:
| I hated GraphQL and all the hype around it. Until I finally got
| how to use it what for.
|
| Same I thought about nest.js, Angular.
|
| All of them hard to understand by heart at beginning, later (a
| few years), you feel it and get value.
|
| Sounds stupid, but I tried to reimplement all the benefits using
| class transformers, zod, custom validators, all others packages.
| And always end up: "alright, graphql does this out of the box".
|
| REST is nice, same as express.js if you create non-production
| code. Reality is you need to love this boilerplate. AI writes
| this anyway.
| ianberdin wrote:
| Is it user friendly for all the apps. It's not. Is it easy to
| understand? No. For beginners? No. For legacy corps? No. For
| public APIs? No.
| hashmap wrote:
| > GraphQL isn't bad. It's just niche. And you probably don't need
| it.
|
| > Especially if your architecture already solved the problem it
| was designed for.
|
| What I need is to not want to fall over dead. REST makes me want
| to fall over dead.
|
| > error handling is harder than it needs to be GraphQL error
| responses are... weird. > Simple errors are easier to reason
| about than elegant ones.
|
| Is this a common sentiment? Looking at a garbled mash of linux or
| whatever tells me a lot more than "500 sorry"
|
| I'm only trying out GraphQL for the first time right now cause
| I'm new with frontend stuff, but from life on the backend having
| a whole class of problems, where you can have the server and
| client agree on what to ask for and what you'll get, be compiled
| away is so nice. I don't actually know if there's something
| better than GraphQL for that, but I wish when people wrote blogs
| like this they'd fill them with more "try these things instead
| for that problem" than simply "this thing isn't as good as you
| think it is you probably don't need it".
| greekrich92 wrote:
| Over a decade of web dev experience and constantly lurking on HN,
| I've never heard the initialism BFF. What is a Backend for
| Frontend and where did that term gain traction?
| storus wrote:
| I thought that the main selling point of GraphQL was a single
| query per SPP argument, i.e. fetch your app state with a single
| query at the beginning instead of waiting for hundreds of REST
| calls. This also goes out of the window when you need to do some
| nested cursor stuff though, i.e. open app with third page
| selected, and inside the page have the second table on the 747th
| row selected.
___________________________________________________________________
(page generated 2025-12-14 20:00 UTC)