[HN Gopher] After 6 years, I'm over GraphQL
___________________________________________________________________
After 6 years, I'm over GraphQL
Author : mattbessey
Score : 851 points
Date : 2024-05-30 08:50 UTC (14 hours ago)
(HTM) web link (bessey.dev)
(TXT) w3m dump (bessey.dev)
| zer00eyz wrote:
| 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.
| jamesrr39 wrote:
| 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 wrote:
| That might be what they meant by "robust permissions model".
| UweSchmidt wrote:
| 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 wrote:
| 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 wrote:
| My guess would be they SSR those pages and partially
| hydrate the page on the client if the user is logged in.
| dumbo-octopus wrote:
| Are they? I have full access to all the Instagram reels,
| posts, comments, etc. friends send me, without being logged
| in.
| Kwpolska wrote:
| Not really, it's 100% business reasons. Facebook and
| especially Instagram used to be much more open to logged-out
| users in the past.
| graemep wrote:
| 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 wrote:
| 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.
| BiteCode_dev wrote:
| 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 wrote:
| Yep, GQL can make sense if you have tons of clients.
| daxfohl wrote:
| 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 wrote:
| Nah, it's one level up having basically everything as an Ent
| (ORM object) with an associated data access policy that does
| that.
| oksteven wrote:
| 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.
| aurareturn wrote:
| 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 wrote:
| agree, it solve problem at FB for sure, that is a good point.
| romanovcode wrote:
| 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 wrote:
| 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 wrote:
| I've also switched to using useReducer.
| hot_gril wrote:
| 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.
| BillyTheKing wrote:
| 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.
| manquer wrote:
| 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
| tisdadd wrote:
| 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.
| kabes wrote:
| True, but rest calls over multiple micro services is even worse
| jamesrr39 wrote:
| 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.
| RedShift1 wrote:
| 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
| { ... }"
| silentguy wrote:
| 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.
| noduerme wrote:
| 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.
| manquer wrote:
| 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
| rockyj wrote:
| 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 wrote:
| 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 wrote:
| I do not share that author's belief about application code.
| cultofmetatron wrote:
| 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 wrote:
| > 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.
| trallnag wrote:
| Usually you put in views between your "private" DB structure
| and GraphQL
| santiagobasulto wrote:
| 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 wrote:
| Hasura, PostGraphile, and Prisma do make it quite a bit easier
| for the backend.
| k__ wrote:
| A few weeks ago, I read that tRPC is an interesting alternative.
| welder wrote:
| 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
| thom wrote:
| 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 wrote:
| 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.
| jojobas wrote:
| It's not graph, and it's not QL.
| dventimi wrote:
| It is QL.
| atsjie wrote:
| 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.
| DanielHB wrote:
| 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.
| dudeinjapan wrote:
| 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!
| beeboobaa3 wrote:
| 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.
| RHSeeger wrote:
| 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?
| serpix wrote:
| 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.
| RHSeeger wrote:
| But GraphQL doesn't allow for infinitely nested queries;
| the query itself has to include as much depth as it wants
| in the response.
|
| > Then we just come back full round trip to REST
|
| Except that GraphQL allows the back end to define the
| full set of fields that are available, and the front end
| can ask for some subset of that. This allows for less
| load; both on the network and on what the back end needs
| to fetch data for.
|
| From a technical perspective, GraphQL is (effectively)
| just a REST API that allows the front end to specify
| which data it wants back.
| danielheath wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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.)
| RHSeeger wrote:
| But as people noted, it's not the "can this get the data"
| unit testing that's a problem here. It's the performance
| issues.
|
| > 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
|
| But that's like giving direct (read) database access to
| someone that was taught the syntax of SQL but not the
| performance implications of the different types of
| queries. Sure, they can get the data they want; but the
| production server may fall over when someone hits the
| front end in a new way. Which is, I think, what a lot of
| people are talking about when they talk about GraphQL
| having load issues based on the front end changing their
| call.
| RHSeeger wrote:
| > It seems there is a recent trend of using adapters that
| expose data stores over graphql automatically, which is
| kind of scary.
|
| I think that's the part where I have a disconnect. To me,
| both REST and GraphQL likely need to hit the database to
| get their data, and I would be writing the code that does
| that. Having the front end's call directly translated to
| database queries seems insane. The same would be true if
| you wrote a REST API that hit the database directly and
| took table/field names from query parameters; only... we
| don't do that because it would be stupid.
| foobarian wrote:
| > 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 wrote:
| 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.
| RHSeeger wrote:
| > and yes, it can be constrained, but this flexibility is
| the whole point
|
| Flexibility within the constraints of what the back end
| can safely support.
|
| To me, the "whole point" of GraphQL is to be able to have
| the client ask for only the data they need, rather than
| have a REST API that returns _everything_ and letting the
| front end throw away what they don't need (which incurs
| more load).
|
| If you can't support returning certain configurations of
| data, then... don't.
| RHSeeger wrote:
| And the client team using a REST API can do the exact
| same thing, by making more calls. There's no real
| difference between "more calls" and "same amount of
| calls, but requests more data".
|
| That being said, it's a lot easier to setup caching for
| REST calls.
| DanielHB wrote:
| > 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 wrote:
| trying to solve org problems with tech just creates more
| problems, allthewhile not actually solving the original
| problem.
| clintonb11 wrote:
| 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 wrote:
| 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.
| smaudet wrote:
| 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 wrote:
| 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
| finack wrote:
| 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.
| gedy wrote:
| > 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.
| fire_lake wrote:
| 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 wrote:
| Yes, GraphQL is a "contract" in the sense that a blank
| check is also a "contract".
| arcticfox wrote:
| 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.
| chuckadams wrote:
| 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...
| afiori wrote:
| > 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)
| vbezhenar wrote:
| REST is just a short name for RPC over JSON. Nobody does
| real Fielding's REST.
| BiteCode_dev wrote:
| 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.
| tomrod wrote:
| 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?
| BiteCode_dev wrote:
| 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 wrote:
| 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 wrote:
| 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.
| chrisandchris wrote:
| 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 wrote:
| That's sort of my expectation too -- it would be nuts to
| provide a user facing system without bounds of some sort.
| chuckadams wrote:
| 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.
| cmgbhm wrote:
| 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.
| strken wrote:
| 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.
| afavour wrote:
| 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.
| jerf wrote:
| 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.
| strken wrote:
| 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 wrote:
| 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.
| hansonkd wrote:
| 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 wrote:
| 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 wrote:
| > 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 wrote:
| In stawberry you make a method per field you want to
| retrieve, I would say it is indeed more complex and
| costly.
| hansonkd wrote:
| 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.
| barrkel wrote:
| 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 wrote:
| > 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 wrote:
| 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 wrote:
| > 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 wrote:
| > 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 wrote:
| > 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 wrote:
| > 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 wrote:
| 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 wrote:
| >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 wrote:
| 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.
| sixdimensional wrote:
| 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.
| smaudet wrote:
| > 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 wrote:
| 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 wrote:
| 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.
| tshaddox wrote:
| 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.
| tuan wrote:
| > 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 ?
| pavel_lishin wrote:
| 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.
| matt_s wrote:
| > 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.
| aaronbrethorst wrote:
| Harder to get a promotion when you're doing something that's
| old, boring, and just works.
| suzzer99 wrote:
| Especially if your job title has "architect" in it.
| apantel wrote:
| The closer you are to the cutting edge, the more sliced up
| you're gonna get.
| hansonkd wrote:
| 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.
| ComputerGuru wrote:
| > 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 wrote:
| 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.
| clintonb11 wrote:
| 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 wrote:
| 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.
| pavel_lishin wrote:
| 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.
| RVuRnvbM2e wrote:
| 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.
| hansonkd wrote:
| 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 wrote:
| A lot of graphql implementation end up moving the n+1
| problem to the query resolver.
| hansonkd wrote:
| Every GQL implementation I have seen explicitly has a way
| to avoid n+1 queries.
| RVuRnvbM2e wrote:
| > 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.
| chuckadams wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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.
| arp242 wrote:
| 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 wrote:
| 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 wrote:
| 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.
| vbezhenar wrote:
| 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.
| datavirtue wrote:
| It's analogous to a specific method in code. No idea why
| people go nuts over this.
| hansonkd wrote:
| 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 wrote:
| 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.
| arp242 wrote:
| 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.
| svieira wrote:
| 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 `transformToRest
| Model(transformToDomainModel(retrieveDbModel(theId)))`
| when the three models happily coincide for a time.
| kiney wrote:
| 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
| nurple wrote:
| 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.
| datavirtue wrote:
| 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 wrote:
| 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 wrote:
| And finally HyperText will progress into the futuristic
| HyperCard
| WD-42 wrote:
| 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 wrote:
| 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 wrote:
| This happens anyway.
| hansonkd wrote:
| 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 wrote:
| 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 wrote:
| Aka never underestimate the power of additional
| complexity to drive bad use, absent familiarity.
| bunderbunder wrote:
| This sounds like more of an org chart problem or a value
| chain management problem than a technical problem.
| throwup238 wrote:
| That's why we have Conway's law.
| bunderbunder wrote:
| 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.
| DangitBobby wrote:
| Frontend devs can write fake API calls which return the
| data they expect in the meantime.
| blowski wrote:
| I've heard this called the "backend-for-frontend"
| pattern.
| marcosdumay wrote:
| 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 wrote:
| > 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!
| riffraff wrote:
| 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 wrote:
| 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 wrote:
| > 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 wrote:
| 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.
| GeneralMaximus wrote:
| 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.
| apsurd wrote:
| > ... 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.
| int_19h wrote:
| 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 wrote:
| 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 wrote:
| 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.
| defen wrote:
| 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.
| evantbyrne wrote:
| 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.
| eddd-ddde wrote:
| 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 wrote:
| 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.
| rbalicki wrote:
| GraphQL gives you this.
| https://relay.dev/docs/guides/persisted-queries/
| theptip wrote:
| 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 wrote:
| 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 wrote:
| OData existed _before_ GraphQL in the wild, it 's
| possible to suggest GraphQL reinvented OData.
|
| https://www.odata.org/
| hansonkd wrote:
| 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 wrote:
| 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 wrote:
| > 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 wrote:
| > 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 wrote:
| 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 wrote:
| 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.
| realusername wrote:
| > 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 wrote:
| > 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 wrote:
| 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 wrote:
| ? 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 wrote:
| 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 wrote:
| 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 wrote:
| Nobody said you should expose your database to the
| outside world. Do you not understand the difference
| between APIs and services?
| hansonkd wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| > 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 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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.
| matt_s wrote:
| 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 wrote:
| > 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 wrote:
| > 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.
| mvdtnz wrote:
| > 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...
| hi-v-rocknroll wrote:
| Perhaps that's the case for server-side transactions and
| ORMs over REST and gRPC to coordinate rather than allowing
| the front-end to diddle with data however it likes.
|
| And, resources with an index option obviously should have a
| db index or unique index.
|
| The challenges with GraphQL are that it makes it too easy
| to DoS services, leak internal data, break referential
| integrity, and there were a great deal of tools,
| infrastructure, and monitoring systems already available
| for REST (and gRPC to a degree).
|
| Company standards for REST and coding style can and should
| be set in the diff review pipeline. Another facet is
| setting standards to minimize duplication of effort or
| exposing a greater attack surface.
| TheSoftwareGuy wrote:
| 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 wrote:
| 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.
| raxxorraxor wrote:
| 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.
| cess11 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| Its not JSON over XML. They're saying JSON REST won over
| _XML and SOAP_.
| int_19h wrote:
| 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 wrote:
| 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 wrote:
| 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.
| LeonenTheDK wrote:
| > 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.
| solidasparagus wrote:
| 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.
| flashgordon wrote:
| >> 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 wrote:
| Now where does Braid-HTTP fit in?!
| bryanrasmussen wrote:
| >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 wrote:
| 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.
| hinkley wrote:
| 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 wrote:
| what's work stealing?
| taeric wrote:
| 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.
| lpapez wrote:
| 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 wrote:
| Curious, I hadn't heard that take on Mongo. Do you have a link
| to some more info on this.
| sswaner wrote:
| https://youtu.be/b2F-DItXtZs?si=rxrMwJVu95WQQt7M
| FrustratedMonky wrote:
| 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 wrote:
| 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 wrote:
| > 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?
| mst wrote:
| MongoDB were the first major player to do that (that I
| know of, at least) back in 2018 - see
| https://www.mongodb.com/legal/licensing/server-side-
| public-l... or hit google for a plethora of people being
| angry about it.
| rglover wrote:
| 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 wrote:
| 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.
| CuriouslyC wrote:
| 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 wrote:
| 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.
| otabdeveloper4 wrote:
| Mongo is great if you want a distributed replicated log.
| Existing tools sorely lack. (Postgres and Kafka are broken by
| design.)
| FridgeSeal wrote:
| Curious as to why you think Kafka is broken by design?
| foobarian wrote:
| > 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 wrote:
| What are the use-cases for graph introspection in any but a
| tiny fraction of cases?
| aobdev wrote:
| 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/
| eYrKEC2 wrote:
| 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.
| hot_gril wrote:
| 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 wrote:
| GraphQL works when you have an army of engineers that are
| able to solve all the perf issues
| hot_gril wrote:
| 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.
| suzzer99 wrote:
| Everything works when you have an army of top-flight
| engineers.
| hot_gril wrote:
| I can name plenty of engineering tasks an army of top
| engineers has failed at, to the point of negatively
| impacting the product.
| suzzer99 wrote:
| Ok, "most things". ;)
| culi wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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.
| purge wrote:
| many of these concerns are mitigated by ensuring you are using
| trusted documents (https://benjie.dev/graphql/trusted-documents)
| julian37 wrote:
| This. For graphql-ruby: https://graphql-
| ruby.org/operation_store/overview
| mst wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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...
| purge wrote:
| postgraphile v5 has significantly improved query
| generation (https://postgraphile.org/postgraphile/next/)
| since moving to grafast (https://grafast.org/grafast/)
| dventimihasura wrote:
| Nice!
| mst wrote:
| > 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 ... :)
| dventimihasura wrote:
| Ahh, I see. Yeah, I suppose some examples in the docs
| would be nice.
|
| Anyway, here's an example with Hasura:
|
| https://gist.github.com/dventimihasura/b3f3c9e7ef1442d8e7
| f16...
| RedShift1 wrote:
| 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 wrote:
| If you're writing you're REST API by hand I'd suggest that you
| may not be doing it optimally.
| keb_ wrote:
| How should you write your REST API?
| doctor_eval wrote:
| 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 wrote:
| I think some of the complaints come from using code to offer
| GraphQL backends rather than just using PostGraphile
| Aeolun wrote:
| 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 wrote:
| IMO even the types are annoying because null is opt-out rather
| than opt-in
| DanielHB wrote:
| 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.
| nesarkvechnep wrote:
| 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 wrote:
| What is that you find so complex about RESTful APIs?
| k__ wrote:
| I assume, it's less about the complexity and more about most
| people not understanding REST.
| DanielHB wrote:
| 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 wrote:
| Bad performance if you haven't heard about HTTP caching.
| REST implies cacheabality.
| baq wrote:
| 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.
| SantiagoElf wrote:
| 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 wrote:
| > 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 wrote:
| 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.
| doctor_eval wrote:
| So you're not familiar with AngularJS, the incompatible
| version 1? Angular 2 was effectively a complete rewrite -
| cleverly using the same name, thereby making it even more
| difficult for us - and the rewrite was done because Google
| Decided. Never again will I trust a Google front end
| library.
|
| Because of my experience, I feel that your position is
| making a slim distinction based on your preferences. All
| the tech you use is built for big corporations, why pick on
| one set of tech just because you don't have the specific
| problems it solves?
|
| For me, for example, K8s properly solves a bunch of
| problems for my small SaaS business, not least of which is
| that I can upgrade my three piddly servers without taking
| my customers offline. My SSL certs get upgraded
| automatically without downtime. My CICD pipeline is simple.
| Logging is much easier. And so on.
|
| I don't understand the disdain for modern, managed K8s at
| all.
| graemep wrote:
| 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.
| david_draco wrote:
| There was a very short window of time when you could make very
| advanced queries over your Facebook friends graph. It was
| awesome.
| simonw wrote:
| Yeah, those were quite something:
| https://www.tumblr.com/actualfacebookgraphsearches
| donatj wrote:
| 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.
| PaulHoule wrote:
| 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 wrote:
| I have used it on multiple projects and liked it, the project
| are still going strong a couple of years after and are
| maintainable.
| cqqxo4zV46cp wrote:
| 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 wrote:
| Not necessarily. Tools like Hasura, PostGraphile, and Prisma
| let you skip out without even having to pay with implementation
| complexity.
| jvans wrote:
| 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 wrote:
| * 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 wrote:
| 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 wrote:
| Same thing in sql. Non null guarantees are great until you
| do a left join.
| jvans wrote:
| 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
| merrywhether wrote:
| 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.
| probabletrain wrote:
| > 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-...
| yonixwm wrote:
| 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...
| quonn wrote:
| 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.
| dudeinjapan wrote:
| I was over GraphQL the moment I looked at the specification.
| tarkin2 wrote:
| 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
| eterps wrote:
| > 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?
| 0-bad-secrotrs wrote:
| 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 wrote:
| 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 wrote:
| 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.
| em-bee wrote:
| 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.
| chasd00 wrote:
| 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?
| tossandthrow wrote:
| 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 wrote:
| >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 wrote:
| What decides what data to include?
|
| Or are you just sending all data the client cloud
| possibly see over?
| scubbo wrote:
| GraphQL "solves" the ability to ignore an unneeded field
| in a response? Revolutionary.
| wruza wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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.
| nevir wrote:
| 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
| culi wrote:
| it sounds like they are just dumping every field to somehow
| show the user without any validation/specific rendering
| logic for each field
| hombre_fatal wrote:
| 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 wrote:
| 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.
| 015a wrote:
| 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.
| amjnsx wrote:
| Sounds like an issue with your team rather than graphql
| tarentel wrote:
| 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.
| culi wrote:
| 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 wrote:
| 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 wrote:
| you can poll or subscribe within GQL. The same solutions
| you'd use with a rest-based api
| squidsoup wrote:
| This is easily fixed by introducing a linter - relay complains
| about unused fields by default.
| pjmlp wrote:
| Unfortunately it has become fashionable in SaaS products to only
| offer GraphQL endpoints, thus whatever we think about it, GraphQL
| it is.
| williamdclt wrote:
| I don't interact with that many SaaS products, but I've never
| seen that
| pjmlp wrote:
| If you want to be pedantic, some do offer REST or GROQ as
| well, which aren't much of an alternative anyway.
| jakubmazanec wrote:
| 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 wrote:
| 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.
| dgb23 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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.
| doctor_eval wrote:
| But if you write the query to use variables, the
| variables are json.
|
| JSON is great (though not perfect) as an interchange
| format, but it's decidedly not a query language.
| meowtimemania wrote:
| i agree with this. Writing queries is the most annoying
| part of graphql
| doctor_eval wrote:
| I just reread my post. I meant to say that GraphQL
| _requests_ , not queries, are JSON.
|
| Of course the query itself is not json, why should it be?
| It describes the shape of a json object, and queries are
| generally pretty static. But the request to the server is
| json, the request variables are json, the result is json,
| and all the json tooling can be used in the responses in
| our clients.
|
| Honestly, one of the reasons I like GraphQL is the fact
| that underlying it all is just JSON.
| nfw2 wrote:
| They are referring to the schema language
| vinnymac wrote:
| 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).
| bluehatbrit wrote:
| 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.
| anonzzzies wrote:
| 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.
| __loam wrote:
| Graphql was routinely an overly complex piece of shit when I was
| forced to deploy software with it.
| CharlieDigital wrote:
| 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.
| hakanderyal wrote:
| 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.
| oreoftw wrote:
| 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.
| probabletrain wrote:
| 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/
| travellingprog wrote:
| TanStack Query (fka React Query) is a REST client similar to
| Apollo Client, with many of the same pros and cons:
| https://tanstack.com/query/latest/docs/framework/react/overv...
| romanhotsiy wrote:
| 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 wrote:
| What do you use to generate your SDK?
| WiseWeasel wrote:
| 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.
| shepherdjerred wrote:
| 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 wrote:
| yeah, you're right!
| martpie wrote:
| 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 wrote:
| I use Express for my web server and OpenAPI for the schema,
| which works like a charm.
| dzonga wrote:
| 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 wrote:
| 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 wrote:
| 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
| strken wrote:
| 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 wrote:
| 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 wrote:
| 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.
| ctvo wrote:
| > 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 wrote:
| 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 wrote:
| 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://faceboo
| k.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/a41aa76ef36471ba07
| b29...
|
| > 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 wrote:
| I stand corrected, I'm the one with a distorted memory of
| the doc.
| Izkata wrote:
| > 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 wrote:
| > 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 wrote:
| 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 wrote:
| 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 wrote:
| Construction is always the wrong metaphor for sw dev.
|
| Think more like marketing campaign or product design.
| randomdata wrote:
| 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 wrote:
| 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".
| herpdyderp wrote:
| 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.
| the_real_cher wrote:
| 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.
| combiBean wrote:
| 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.
| 6510 wrote:
| I post sql queries to my backend then match them against the
| exact string. The lack of flexibility is on purpose.
| nprateem wrote:
| 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 wrote:
| The N+1 problem doesn't exist on any project that uses, say,
| Hasura.
| jhatemyjob wrote:
| Are you really surprised though? Like you alluded, people use
| Kubernetes and Bazel just because it has the big ol' G stamp on
| it. GraphQL is no different
|
| (Well... slightly different. It's the FB stamp, not the G
| stamp)
| surfingdino wrote:
| 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 wrote:
| > 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.
| azangru wrote:
| 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 wrote:
| What do you dislike about React?
| azangru wrote:
| 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...
| diggan wrote:
| > [0] https://blogs.windows.com/msedgedev/2024/05/28/an-
| even-faste...
|
| Maybe I'm missing something obvious, but React isn't
| mentioned in that post. Maybe you put the wrong URL?
| azangru wrote:
| Odd, I thought I saw something about React in Microsoft's
| communications as well. Anyway, here is the horse's
| mouth: https://toot.cafe/@slightlyoff/112521248529973776
| chrisandchris wrote:
| 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.
| yCombLinks wrote:
| 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.
| squidsoup wrote:
| I don't think that's true, web components are not
| equivalent to libraries like react and vue.
| shudza wrote:
| 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.
| icar wrote:
| 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.
| abound wrote:
| 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.
| ko_pivot wrote:
| +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 wrote:
| Huge fans of Buf Connect. We run vanilla gRPC servers on the
| backend and have a typed experience through to the frontend
| troupo wrote:
| > 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 wrote:
| 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?
| pants2 wrote:
| 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.
| culi wrote:
| 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(tm)"
| feoren wrote:
| "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.
| unsupp0rted wrote:
| 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.
| dventimi wrote:
| 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.
| aeonik wrote:
| 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 wrote:
| > 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.
| gmassman wrote:
| 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 wrote:
| 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.
| vitiral wrote:
| 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 wrote:
| > 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 wrote:
| And GraphQL has no real benefits over SQL? If so... I'm not
| sold
| crabbone wrote:
| 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 wrote:
| > 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
| dcre wrote:
| "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.
| dartos wrote:
| 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.
| ksec wrote:
| >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.
| hansonkd wrote:
| 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.
| theK wrote:
| 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 wrote:
| > I find it a bit poor though that the only recommended
| alternative is OpenAPI rest APIs.
|
| What are your recommendations? gRpc?
| theK wrote:
| 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 wrote:
| Someone above recommended https://connectrpc.com/ , which
| looks quite promising to me. Maybe I'll get time to play with
| it today
| foobarian wrote:
| > 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 wrote:
| 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 wrote:
| 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.
| greens231 wrote:
| 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
| casperb wrote:
| 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.
| vendiddy wrote:
| 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.
| knlam wrote:
| 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 ... }
|
| ```
| pavel_lishin wrote:
| 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?
| vvpan wrote:
| 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.
| presentation wrote:
| 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.
| eatsyourtacos wrote:
| 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 wrote:
| You should have looked at the schema.
|
| It indeed seems like GraphQL saved your client in this case.
| eatsyourtacos wrote:
| >It indeed seems like GraphQL saved your client in this case.
|
| Yeah.. no.
| steve_adams_86 wrote:
| 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 wrote:
| 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/
| Calamitous wrote:
| Fundamentally, GraphQL is a _query language_, but people keep
| trying to build/use it as an _API_.
| remus wrote:
| 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.
| petesergeant wrote:
| 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
| mannyv wrote:
| 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.
| deadbabe wrote:
| 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.
| adeptima wrote:
| 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 wrote:
| 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.
| chuckadams wrote:
| 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).
| moribvndvs wrote:
| 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 wrote:
| > (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.
| drpossum wrote:
| > used it in a small project, and liked almost every bit of it
|
| This is the difference
| Hamuko wrote:
| 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?
| chuckadams wrote:
| 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.
| stratigos wrote:
| 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.
| electrondood wrote:
| 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.
| Ozzie_osman wrote:
| 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.
| awirick wrote:
| 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 wrote:
| OpenAPI can do graphs too, since you can put in refs to objects
| that can themselves have refs to other objects, possibly
| recursively.
| mcdonje wrote:
| >1. Write a succinct human readable TypeSpec schema >2. Generate
| an OpenAPI YAML spec from it
|
| Why? Isn't YAML human readable?
| emlos wrote:
| 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.
| emorning3 wrote:
| Odata is 80% of GraphQL with only 20% of the hassle.
| finack wrote:
| 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?
| hot_gril wrote:
| I started at the same conclusion of using OpenAPI and never
| ventured into GraphQL cause I only had one client.
| mirekrusin wrote:
| 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 wrote:
| > 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 wrote:
| 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.
| mbleigh wrote:
| 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.
| victor106 wrote:
| 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.
| rglover wrote:
| 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 wrote:
| 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.
| hot_gril wrote:
| (To be clear, OpenAPI was the baseline I was already
| comfortable using, and GraphQL was the heavier approach I
| wasn't sure about.)
| powersurge360 wrote:
| 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 wrote:
| Sounds like you are describing the Backend For Frontend (BFF)
| pattern and I also quite like it.
| smrtinsert wrote:
| Graphql via spring is easy integrates seamlessly. Obviously stick
| to its core use cases and it will go great.
| rambojohnson wrote:
| yes, let's conflate bad API / schema design with GraphQL / the
| technology being the problem.
| edude03 wrote:
| 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.
| phaedryx wrote:
| 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.
| SJC_Hacker wrote:
| 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.
| joshstrange wrote:
| 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 wrote:
| 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.
| nkozyra wrote:
| > 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.
| AaronFriel wrote:
| 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 wrote:
| > 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 wrote:
| 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.
| andreimackenzie wrote:
| 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.
| Onawa wrote:
| EdgeDB? Graph database built on top of Postgres so you can do
| row-based auth as well.
|
| https://www.edgedb.com/blog/edgedb-5-introducing-
| passwordles...
| burutthrow1234 wrote:
| 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.
| jack_riminton wrote:
| 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 Resume Driven Development, together with the
| dividing wall between front and backends is why FE frameworks
| have got so hideously and needlessly complex imo
| ForHackernews wrote:
| Sounds good to me. I'll do GraphQL for $250k.
| sodapopcan wrote:
| 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!
| peter_l_downs wrote:
| Ha, I gave this exact speech at the 2021 Hasura Conference
| [0]. You hit the nail on the head.
|
| Sometime in 2022 we switched back to REST endpoints for all
| of the reasons listed in the OP's article. Didn't hurt that
| we had hired for more fullstack engineers rather than
| "frontend only", so they saw exactly why we wanted to make
| the switch.
|
| EDIT: to be fair, using Graphql and Hasura absolutely did
| help us iterate more quickly early on. But once we had a
| firmer idea of what we wanted to build, switching to REST was
| the right call. One of our most talented engineers wrote some
| helpers to make sure the frontend types were synced up with
| the backend types and that pretty much replaced the main
| benefit of using Graphql.
|
| [0] https://hasura.io/events/hasura-con-2021/speakers/peter-
| down...
| giantg2 wrote:
| 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.
| lcnmrn wrote:
| Someone like you made me quit my first job as developer. He
| implemented a Clojure + GraphQL nightmare.
| joshstrange wrote:
| 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.
| subsaharancoder wrote:
| Did the person use Lacinia?
| https://lacinia.readthedocs.io/en/latest/index.html
| nfw2 wrote:
| 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
| joegibbs wrote:
| Yeah but then you've basically just remade REST, but the
| queries are stored in the frontend instead.
| wasyl wrote:
| I don't understand this argument, how is it "remade REST"
| if you still don't need to implement and maintain an
| endpoint with exactly the data that clients need?
| Persisted/whitelisted queries require much less backend
| effort, and are decidedly different from REST, the only
| similarity is in having a closed set of possible actions.
| Perhaps you're thinking in terms of public APIs where I
| agree limiting available GraphQL queries makes little
| sense. But for internal APIs, whitelisting whatever queries
| current clients need isn't any less convenient
| rbalicki wrote:
| 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.
| teaearlgraycold wrote:
| 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.
| esafak wrote:
| You can type your REST API too. https://restfulapi.net/json-
| schema/
| rbalicki wrote:
| 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 wrote:
| swr can handle the first issue you mentioned just fine.
| rbalicki wrote:
| I'm not sure I follow. Are you saying swr allows for
| fragments and deduplication?
|
| If you don't have fragments (in particular, if you have a
| single call to an swr hook at the root), then you have
| implicit deduplication. But then you run into the issue
| of it being unclear whether you can remove a given field
| when a subcomponent stops using it -- you have to check
| whether any other subcomponent happens to use that.
|
| And if you have many separate queries, you're
| architecting in waterfalls. But you have clarity about
| who uses which field.
| awongh wrote:
| 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 wrote:
| 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?
| albertgoeswoof wrote:
| 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
| rezonant wrote:
| Also there is no standard for exposing the schema, and
| sometimes there isn't a schema _at all_. Sometimes a
| vendor will have the schema downloadable from their dev
| docs, sometimes it will be an endpoint that serves it up,
| and sometimes they just don 't give it to you and expect
| you to use GraphQL Explorer directly to discover what you
| can do. When I encountered this I figured surely GraphQL
| Explorer must be _fetching_ the schema, but I guess this
| is not always the case, as I never was able to get a
| complete schema that worked with the tooling. For that
| vendor, there was no way to generate client code for the
| schema using one of the many GraphQL client library
| generator frameworks.
| awongh wrote:
| 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.
| vdfs wrote:
| > 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)
| rezonant wrote:
| This has been my experience when integrating with a
| vendor's APIs where they've been bit by the GraphQL bug.
| They have a full featured, stable and easy to use REST API,
| and then a poorly implemented GraphQL solution that doesn't
| cover all the use cases of the original API, and new
| features only appear in the GraphQL schema, so you have to
| be stuck using both and it's a horrible experience.
|
| I'm also not personally a fan of having my API queries on
| the frontend span multiple lines for things that with a
| good REST design with OpenAPI are a single method call, but
| all too often the calls I would need to make to the
| vendor's GraphQL API were exactly this: did not make use of
| any of GraphQL's query features, and were effectively just
| RPC calls.
| pyr0hu wrote:
| 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 wrote:
| 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.
| mattacular wrote:
| 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.
| bilater wrote:
| 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.
| unnouinceput wrote:
| 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.
| davidw wrote:
| 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.
| victor9000 wrote:
| My experience is that a stable graphql server is dependent on
| well behaved clients, which is not something you control.
| nojvek wrote:
| 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.
| frabjoused wrote:
| 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.
| jupp0r wrote:
| 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).
| iamyemeth wrote:
| Why, after 6 years, I'm over increased complexity for marginal
| benefit. Sounds like most things developed and promoted by FANG
| patricius wrote:
| 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
| ttfkam wrote:
| 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 wrote:
| 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.
| valenterry wrote:
| 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.
| rbalicki wrote:
| 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!
| garydevenay wrote:
| 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.
| nailer wrote:
| 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.
| rootedbox wrote:
| GraphQL.. when people didn't learn their lessons from SOAP..
| kabes wrote:
| 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.
| santoshalper wrote:
| 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.
| mocamoca wrote:
| 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)
| andy_ppp wrote:
| 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!?
| qaq wrote:
| 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.
| GenCuriosity wrote:
| 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
| PurpleRamen wrote:
| > 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 wrote:
| I think you replied to the wrong post :)
| rootusrootus wrote:
| We are in the process of winding down our biggest GraphQL
| attempt, after years of trying to make it work well. Nobody is
| feeling sad to watch it go, that is for sure.
| michilehr wrote:
| I totally agree with every point.
|
| GraphQL can be very powerful, but also very dangerous.
| megalord wrote:
| Many of you guys probably don't even need API for web
| development. Same as we didn't. We rewrote codebase, removed
| React and Graphql part and now Django serves html. Win win for
| everyone.
|
| We don't have mobile app and don't even plan, but if we do, we
| always can implement some rest api.
| rezonant wrote:
| I have never bought the GraphQL hype, but have never explained my
| rationale as well as this article does. Kudos Matt on succinctly
| nailing the issues here.
|
| As for how to tackle things today, I alternate between
| REST+OpenAPI and RPC models for communication. I am certainly
| biased as I have my own typed open source RPC library (Conduit)
| which is layered on top of arbitrary message passing transports
| such as WebSockets, but as of yet it's only suited for
| Typescript-based clients -- REST+OpenAPI is a better fit for an
| API with many consumers.
|
| But for dynamic client/server and client/client single-
| implementor communication needs, I go with RPC.
| localfirst wrote:
| You notice Facebook is increasing complexity across the board?
|
| Frontend - React
|
| Backend - GraphQL
|
| What's extra creepy is the private equity firms squeezing this
| space dry
___________________________________________________________________
(page generated 2024-05-30 23:00 UTC)