[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)