GraphQL kinda sucks

691 points by randytandy 3 days ago

Graphql is great, but is totally over hyped. This is probably more of a rant or a frustrated dev outburst.

but beginner to mid level developers are lead down the path of USE GRAPHQL especially on youtube... and this is just unfair and wrong.

The good:

- It makes working with describing the data you want easy

- It can save you bandwidth. Get what you ask for and no more

- It makes documentation for data consumers easy

- It can make subscription easier for you to use

- Can let you federate API calls

The bad

- It is actually a pain to use, depending on the backend you are using you'll have to manage

two or more type systems if there are no code first generates in your language

- It doesn't support map/tables/dictionaries. This is actually huge. I get that there might be

some pattern where you don't want to allow this but for the majority of situations working with json api's you'll end up with a {[key: string] : T} somewhere

- No clear path for Api versioning you'll end up with MyQueryV1.01 MyQueryV1.02 MyQueryV1.03

Don't use Graphql unless you're managing a solution/problem set that facebook intended graphql for

Invest your time in a simpler solution then running to GraphQL first

thanks for reading my ted talk

please any senior dev's drop your wise words so that any new dev's can avoid tarpits

stickfigure 3 days ago

The biggest problem with graphql is that you have to do a lot of non-obvious work to harden your system against DOS attacks or people that want to fly by and download your whole database. It's easy to construct a query which puts unreasonable load on your system.

The more fine-grained nature of boring REST calls makes it more easy to control client impact on the system.

If you want to see the kind of work you actually need to put in to make a graphql API, look at Shopify. They have rate limits based on quantity of data returned. Cursors and pagination. The schema is a huge ugly mess with extra layers that never show up in the pretty examples of GraphQL on the internet.

Note that even if you use graphql for a private api to your web client, folks will reverse engineer it and use it for their own purposes. There are no private apis on the web.

I'm not a fan of graphql for anything that the public could see. It's somewhat akin to exposing a SQL interface; it opens up too many avenues of trouble. Keep public communication channels as dumb as possible.

  • softfalcon 2 days ago

    We avoid this by statically analyzing the queries that are used by the client, generating id’ed persisted queries for them, and only allowing those to be run if you’re un-authenticated/a regular user.

    We also have user roles, which, if you’re an admin, you can run raw queries of whatever you want, but basic users are locked to the persisted query options.

    It’s pretty cool, definitely adds complexity to our builds/permissions, but it works. We rolled our own, but I think Apollo GraphQL supports this out of the box now.

    Not saying people should use GraphQL for everything though. It’s kind of overkill for a lot of apps.

    • PragmaticPulp 2 days ago

      > We avoid this by statically analyzing the queries that are used by the client, generating id’ed persisted queries for them, and only allowing those to be run if you’re un-authenticated/a regular user.

      I worked with a team that was going down a similar path. At some point it felt like they were reinventing REST on top of GraphQL with a strict set of predefined queries and result shapes.

      They hadn't gone too deep into GraphQL tooling so we just switched to REST and implemented those predefined queries. Had a separate, developer-only GraphQL endpoint for prototyping things for a while, but the production stuff was easier to just build out as plain old REST.

      • softfalcon 2 days ago

        One of the objectives of GraphQL is to replace REST, so yes, you’re right, it’s re-inventing REST.

        I’m not going to argue whether one is better than the other implementation wise. That’s purely personal preference.

        GraphQL has one super power though. I have access to an API directly and can save bandwidth by only querying and returning what I explicitly want in the data. That plus the allowed query rules stuff comes free in Apollo GraphQL now. At scale, this is huge for our bandwidth cost savings.

        A second big win is federation of many GraphQL schemas under one giant god schema. This is useful when you are a big company, merging two architectures with different API’s together under one umbrella. You can define the mappings from the child schemas to the god schema in another spec that has no code, just a federation schema. Again, you can do this in REST too with layered API’s, but GraphQL arguably makes it somewhat easier to do this with just config files.

        I also find that out of the box, the type safety guarantees of GraphQL are a lot cleaner/batteries include than the REST work I did the many years prior.

        It’s all do-able with either tech and you are correct in feeling like it’s re-inventing the wheel. It is, and that’s purely a business decision to make money pivoting devs to a new library/environment.

        I won’t judge you for wanting to stick with REST. It’s tried and true methods that will work for many many use cases. To each their own!

        • arinlen 2 days ago

          > I have access to an API directly and can save bandwidth by only querying and returning what I explicitly want in the data.

          I don't see how REST is not able to do this, not to mention that REST is very well suited for HTTP caching.

        • L0stLink 2 days ago

          Saving bandwidth is really not the actual super power. The main advantage is being able to save network requests by fetching all required data in the same request.

          • arinlen 2 days ago

            > The main advantage is being able to save network requests by fetching all required data in the same request.

            This is not really GraphQL's selling point.

            GraphQL's only selling point is this handwaving-driven promise that dev teams no longer need backend work to get an API that returns the data they want.

            The promise is that frontend teams simply put together a query and the server magically returns what they want.

            Of course the people promising this magic just so happen to be the same people trying to sell you backend services.

          • seelmobile 2 days ago

            Agreed - REST APIs can include a field mask or similar for sparse selection on a single entity but you'll still need several requests to fetch fields on related entities.

        • davewritescode 2 days ago

          I just wanted to hop in and agree with you. I’m still think REST APIs have their place and are easier to work with. If someone had recommended GraphQL 5 years ago I would’ve been against it but Apollo is good enough that I think it’s a fairly safe choice for teams to make.

          One thing you do need to watch for is preventing clients from doing stupid things by allow listing queries or implementing some sort of query cost analysis.

  • ewittern 2 days ago

    We did research on solving the DOS issue using static analysis at IBM (cf. https://arxiv.org/pdf/2009.05632.pdf). Our findings were that static analysis allows to determine (relatively strict) upper bounds on query complexity, which we assessed for two production GraphQL APIs (GitHub and Yelp). However, the static analysis requires some configuration to determine the (maximum) size of lists.

    I was later involved in productising said research into an API gateway (called DataPower) offered by IBM. We implemented our GraphQL static analysis in a quite flexible and performant way (all of GraphQL's query validation and the static analysis are implemented in C++). The required configuration for the static analysis can be provided using GraphQL schema directives (cf. https://ibm.github.io/graphql-specs/cost-spec.html). Unfortunately, DataPower is quite inaccessible to the common developer.

    I find that persisted queries are a very interesting approach to also solve this issue. They still grant developers the full flexibility to define queries during development, but then require providers to validate and vet queries only once before persisting them (instead of validating and vetting queries on every request). This has huge benefits for runtime performance, of course.

  • thr0wawayf00 3 days ago

    It's also not that hard to implement attribute filtering with REST endpoints. People make a big deal about being able to control the shape of your API responses with GraphQL, but this completely achievable with standard REST APIs as well.

    • tshaddox 3 days ago

      Sure, you could have a syntax for requesting (potentially recursive) nested resources in the query string of a REST API, and there are some systems that do something close [0], but if you do it’s probably a less friendly syntax than GraphQL and has all the same problems as GraphQL regarding performance and rate limiting.

      [0]

      A very simple convention for including nested resources in a JSON API: https://www.jsonapi.net/usage/reading/including-relationship...

      A totally cool but kinda over the top library that exposes a REST API over your database with a very GraphQLesque query string syntax that supports recursively nested resource inclusion, filtering, etc.: https://postgrest.org/en/stable/api.html#nested-embedding

      • ryanbrunner 2 days ago

        99% of the time you don't need to be recursive though. Field filtering with 1 level of expansion for related resources solves 95% of problems for you, and if you're implementing something on your own API, you can have a custom route for the 5%.

        GraphQL falls into the same trap that a lot of things do IMO - it assumes that because 5% of things are complex, that you need a solution that can deal with that complexity for 100% of your API, which needlessly complicates everything else.

      • krainboltgreene 2 days ago

        > Sure, you could have a syntax for requesting (potentially recursive) nested resources in the query string of a REST API

        Or you could just make an endpoint that gives you the data you want.

        • imtringued 2 days ago

          That endpoint has to be unique for the client, otherwise someone else could abuse this API and when you filter out an attribute the rogue user depends on, you break their application.

          • krainboltgreene 2 days ago

            No it doesn't. It's just a GET request with a parameter or two. People make this stuff so hard when it doesn't need to be.

      • ec109685 2 days ago

        Agree with this. We created our own nested query language using matrix params and path separators to let the client query for nested sub-resources, including filters against collections.

        It’s pretty neat but nice graphql standardized it so things like consoles and other tools can be written against it.

  • jensneuse 2 days ago

    We solved this by turning GraphQL into a compile time problem and replacing it with JSON-RPC as the transport, keeping GraphQL entirely hidden on the server. It's not just great for security and performance reasons, but also comes with a lot of other benefits, like you can inject claims into Operations. Here's some more info: https://docs.wundergraph.com/docs/features/graphql-to-json-r...

  • pan69 3 days ago

    > Note that even if you use graphql for a private api to your web client, folks will reverse engineer it and use it for their own purposes. There are no private apis on the web.

    How is this a GraphQL specific problem?

    • agucova 2 days ago

      At least compared to classical REST, usually access is limited to whatever the programmer explicitly chose to add, instead of being open by default.

      • Aeolun 2 days ago

        That’s weird. You explicitly choose what to add to your GraphQL API too. If you’re just setting up a random library that exposes your entire database, that’s no fault of GraphQL.

        • dhritzkiv 2 days ago

          Yeah, I caught that too. A lot of comments sounds like they're relying on Prisma/Husara/etc. to map directly to the database. I'm sure it's fine for some use cases (such as when prototyping), but I prefer to design and build out GraphQL APIs with a more UI/product-centric approach, which hide most of the database details.

        • mbfg 2 days ago

          I think it's a marketing problem. GraphQL can easily sound like "Give the entire schema to your users and let them decide what to query for". If you look at various GraphQL supportive websites, that is a common anthem. You don't get that marketing from REST. REST says "decide what's good for them".

          Obviously you can do either in either. But i definitely think the marketing is world's apart.

          So when people come to a problem, if they are not super strong in their understanding of what will be a good solution, they generally implement what the platform markets.

    • crabmusket 2 days ago

      It's not, but the OP is saying this to pre-empt the "just use GraphQL for private APIs" defence.

  • wallfacer120 2 days ago

    How could someone reverse engineer anything other than your data model from gql queries?

  • SnowHill9902 3 days ago

    > It's easy to construct a query which puts unreasonable load on your system.

    Can you give an example?

    • pdpi 3 days ago

      Details will depend on your schema, but the moral equivalent of “SELECT * FROM master_table” is a good start.

      • withinboredom 3 days ago

        Have you seen the “turn your database into a graphql schema” products? I shudder at the poor souls who used those products. I mean, I assume they are decent products, but man, it’s got to be so easy to screw it up and literally expose too much…

        • throwawaymaths 2 days ago

          Hasura seems to be fine which we use internally in our company, though to be honest I don't do any complex queries and I don't think anyone is doing aggressively nested joins.

          • acdha 2 days ago

            I think that can be part of the problem: if you use it for a few things which make sense, you get used to it and everyone thinks it's pretty solid after a while and probably starts using and likely exposing it in other areas. Then you get someone new writing different code or a clever attacker and it turns out there was a lot of room to expose unintended data or create performance issues.

            • throwawaymaths 2 days ago

              I don't think hasura allows unbounded queries by default? I'm not 100% sure though, I didn't set it up at where I work.

      • stickfigure 2 days ago

        It's actually worse than that, because with graphql you can create a single query which is the moral equivalent of:

        SELECT * FROM master_table LEFT JOIN sub_table LEFT JOIN sub_sub_table LEFT_JOIN sub_sub_sub_table...

        ...which is effectively "dump everything". In a REST environment you'll at least need a lot more individual requests - that's both the blessing and curse.

  • humbleMouse 3 days ago

    That’s exactly what it is, a made up sql layer over sql exposing a special port. Ridiculous.

mLuby 3 days ago

Having worked in big tech and small startups, I think GraphQL is a brilliant way to solve an organizational problem that massive tech companies have.

It's that the team maintaining the API is different from the team that needs changes to the API. Due to the scale of the organization the latter doesn't have the access or know-how to easily add fields to that API themselves, so they have to wait for the maintainers to add the work to their roadmap and get back to it in a few quarters. Relevant Krazam: https://www.youtube.com/watch?v=y8OnoxKotPQ

At a small start-up, if the GET /foo/:fooId/bar/ endpoint is missing a field baz you need, you can usually just add it yourself and move on.

  • demarq 3 days ago

    That's the theory. In my experience at both large and small organisations is that NONE of the theory makes it into practice.

    Some reasons:

    - Front end devs save time by.... sharing queries. So component B ends up fetching records it has no use for because its sharing GQL with component A.

    - Backenders never optimise column selection. You may think you are really optimising by sending a GQL query for one column, but the backend will go ahead and collect ALL the columns and then "filter" down the data that was asked for.

    - Backenders can also forget to handle denormalisation. If you query related many to many records but the GQL only asks for related ids of implementations will go ahead and do a full join instead of just returning results from the bridge table.

    - Frontenders aren't even aware you can send multiple graphql GraphL requests simultaneously.

    GraphQL is great, but any technology is limited by how well people can extract its value. I personally feel sometime we'd be better off with REST, or at least make sure people receive the training to use GraphQL effectively.

    • squidsoup 3 days ago

      > Front end devs save time by.... sharing queries. So component B ends up fetching records it has no use for because its sharing GQL with component A

      An unfortunate problem that really only exists with Apollo. Facebook’s graphql client, relay, does not have this issue as it requires each component to explicitly declare its data dependencies.

      • acdha 2 days ago

        > Facebook’s graphql client, relay, does not have this issue as it requires each component to explicitly declare its data dependencies

        In the scenario described, wouldn't this lead to the same problem because someone copied the code or reused a utility from another project and so they have at least the superset of those dependencies plus whatever new ones they added?

      • zbentley 2 days ago

        > really only exists with Apollo

        Citation needed. If two components call into the same data fetching utility for expediency's sake, and that utility queries data that one or both components do not need, you have this problem. What makes that uniquely likely with Apollo?

        • andrewingram a day ago

          It’s more that compared to Relay, which is explicitly designed around preventing components using data they didn’t explicitly declare as a dependency, Apollo (along with most other GraphQL clients) doesn’t go that extra mile.

          Whether it’s a React component, or a just a plain old function, Relay has mechanisms to prevent the kind of problem you’re describing. It has a steep learning curve, but it’s very well considered.

  • the_mitsuhiko 3 days ago

    In many ways you also need to be a massive tech company to not create a massive scalability problem. The first time someone ships a shitty query to a large user base on a mobile app you are now dealing with the consequences of a frontend engineer creating a bad query you can not kill quickly any more.

    Making scalable, well performing queries work is nontrivial, particularly with the current ecosystem of GraphQL libraries. The main workaround for this provided appears to be directly mapping GraphQL to an ORM.

  • makeitdouble 3 days ago

    I used to see GraphQL (and to an uglier respect Soap like interfaces) as complicated solutions to that problem you describe.

    But more and more, I think Backend For Frontends solve this issue in a much better way. And of course that idea isn’t new and Yahoo for instance had that kind of architecture.

    Frontend teams get to adjust by themselves a simple interface to their needs, and backend teams can provide more info through internal APIs with less restrictions than if it was directly exposed to the outside.

    • gedy 3 days ago

      I'm not following if you think GraphQL is a bad fit still, but we used GraphQL with the BFF pattern, and it was nice to use from Frontend to BFF. The backend services would use REST or whatever appropriate behind the BFF.

      • makeitdouble 3 days ago

        I see GraphQL as unneeded if you already have a BFF managed by front teams.

        Going with basic REST gives you simpler caching/optimisation paths, more straightforward mapping between the front request and the backend calls, and it makes it easier for other teams to look at what you’re doing and comment on/fix stuff as needed. GraphQL would be pure syntax sugar, and I’m not sure it would be worth the trade-off.

        • gedy 2 days ago

          > more straightforward mapping between the front request and the backend calls,

          I disagree, at least compared to something like Apollo Server or Hasura. The mapping is much easier, especially if you consider things like resolvers having parts of the schema going to different backend servers, API endpoints, separate caching, etc.

          We tried to do this manually via a REST server, and found that we were just reinventing something like Apollo, but badly.

    • kbumsik 3 days ago

      You can use GraphQL for BFF btw.

    • no_wizard 3 days ago

      Do you have any reference material for the Yahoo architecture?

      • makeitdouble 3 days ago

        It was pretty basic so I’m not sure how much it was talked outside of Yahoo. I see this presentation http://www.radwin.org/michael/talks/php-at-yahoo-zend2005.pd... providing an overview, but otherwise the basic principle was to have each addressable web server host an apache with a routing module, and that module will map a request path to a cgi file.

        With that structure you can have any number of layers with your front call and the different business abstractions all representated by an API (let’s say you want a user’s average engagement with a service, you’d hit the high level API, which will fetch access stats from another API, which rely on a lower level API which goes through another separate layer managing DB cache etc.

        Most of these call are of course internal to a data center.

  • masklinn 3 days ago

    I think an other thing with graphql is it reduces friction when trying to discover what your API should be.

    So what you can do is some sort of generative graphql thingie when doing your initial iteration, with the client hitting whatever is convenient (in that situation you'd just expose the entire backend unprotected).

    Once the needs have gelled out you strip it out and replace the graphql queries by bespoke API endpoints.

    • ryanbrunner 2 days ago

      In my experience, "let's do something non-scalable and obviously wrong while we're exploring the problem space and replace it with something better before shipping" reduces to "let's do something non-scalable and ship to production" 100% of the time.

      • Aeolun 2 days ago

        So you are saying it works? At least all the production systems where we’ve done this work fine, they’re just inefficient, feel vaguely dirty, and are unpleasant to work on. They’re still bringing in boatloads of money though.

        • ryanbrunner 2 days ago

          I think the risk with unrestricted access to your database via GraphQL is that it's potentially a very easy DOS attack sitting waiting to be abused, and potentially a security risk if there's some information you shouldn't be exposing (as a very easy example, allowing unrestricted access to a user database would reveal password hashes, reset tokens, etc. which should never be available in a API).

          I'm a fan of YAGNI, but basic security and leaving your system trivially vulnerable to attacks are a couple of exceptions in my mind.

    • coffee_beqn 3 days ago

      I just have never had this as a problem having worked on many APIs at many companies. Usually we decide what we want to work on and the frontend/full stack can read the documentation / chat with the backend engineers if it’s not clear. At no point is “discoverability” a issue

      • masklinn 3 days ago

        The discoverability I’m talking about is not about knowing what the API is, it’s finding out what the API should be.

  • danabrams 3 days ago

    100% agree that it’s about dependence on other teams. That said, I’d much rather that we were communicating across a well defined api boundary, rather than a graphql api. You could, of course, very easily do this with an api layer in the middle.

    • YZF 3 days ago

      Nobody seems to get the idea of building software out of pieces with well defined APIs any more </rant>. I would say it's not possible to build large software without adhering to this principle but I seem to be proven wrong. You can build large poor quality software and just throw more people at it.

      The other part about team dependence is very true but it also shows a lack of knowledge/thinking/care by whoever formed the teams. It seemed for a while Amazon had things right both in terms of boundaries of teams and in terms of forcing people to use APIs- not sure what they do these days.

      • pphysch 3 days ago

        This is one of the strengths of gRPC, it forces and centralizes the (mostly type safe) API design from the get-go.

        Also tends to use a lot less bandwidth.

        • withinboredom 3 days ago

          The biggest issue with GRPC is that it is only suitable for stateful languages (iow, languages that can hold values and share them between requests). GRPC is basically worthless for stateless languages and unusable. These stateless languages also don’t work well for websockets either, so it is what it is.

          Until they solve the stateful part, I’m not using it or recommending it to be used anywhere. Bandwidth is cheap, type safety is overrated, and compute is expensive.

          • YZF 3 days ago

            What's a "stateful language"? Can you give an example here? gRPC is orthogonal to whether an API relies on state or not.

          • pphysch 3 days ago

            Is this bait? Lol

      • ako 3 days ago

        What is a well defined API to access a lot of related datasets if you have 100s of external users, using it for 10s of different types of use cases?

        Compare it to a database, what if you couldn't use random queries with SQL, but only had the option to call stored procedures?

        • YZF 3 days ago

          It's the narrowest abstraction fitting those use cases. A database by its nature is a generic component. So sure, the piece of your software that's "SQL database" has a SQL interface, pretty quickly you'd want some abstractions on top of that around the different uses of that database.

          The problem is when genericity diffuses its way into a large system it becomes impossible to maintain. How do you refactor a code base when everything everywhere is just SQL queries. If you want to change the schema how do you know you're not breaking anything? The short answer is you don't and so the software becomes incredibly brittle. The common workaround is testing but you can never test everything and now your tests also become coupled to everything else making things even more difficult to change.

          The database in your example, while being generic is already an abstraction of sorts. Now if you're building lessay gmail the external users should see "create email", "get all emails", vs. issuing SQL queries to the database. That makes it easier to change the two pieces (client and server in this simplified example).

  • jonhohle 3 days ago

    If that field isn’t populated aren’t you in the exact same spot?

    • vikR0001 3 days ago

      Let's say you need to get a field back that is already in the database table, but that wasn't previously returned by the GraphQL endpoint. All you have to do on the front end is ask for it and GraphQL will populate it for you on the server.

      • dragon-hn 3 days ago

        If your GraphQL schema is just a mapping of database tables, in my experience you are in for a world of hurt in the future.

        • crispyalmond 3 days ago

          At my workplace they made this decision before I started and I can fully agree with this. It's essentially a typed REST without any of the benefits. No joins, everything is multiple calls away to perform a "full" query.

          I don't even want to think about undoing this mess.

        • vidarh 3 days ago

          It's possible to do this without it getting painful, but you need to annotate the database schema with a lot of meta data.

          We don't use GraphQL, but we do use an API that is mostly generated from meta data about the schema and permissions on a per field basis, with the ability to override on a per table basis.

          To the API consumer it's invisible if they're referring to something that refers directly to a real database columns or to a method on a model class that doesn't correspond directly to the database (e.g. the user "password" attribute is

          Effectively there are two schemas: the API schema and the database schema, it's just that the API schema is "prepopulated" from introspecting the database schema using Sequel (Ruby ORM), with the model classes translating between the two, with a synthesised default mapping.

          The "API schema" includes more granular type information suitable for the frontend, and permissions, including type information returned to the frontend to provide default client side form rendering and validations (also enforced on the server, of course). It also auto-generates documentation pages with example data, inspired by Airtable's doc pages.

          But key to avoiding what you describe is that these are all easily overridable defaults, and the permissions default to allowing no columns, so while the db schema introspection makes it quick to expose things where a direct mapping makes sense, it also makes it easy to avoid.

          Unlike GraphQL we explicitly avoided allowing you to request arbitrary complex sets of data, but what you can do is expose queries by defining model metadata for them that either wraps suitable views or custom queries. We have a UI to allow us to define and store custom queries and views for e.g. reporting needs, so we can prototype new API needs in the browser writing just queries with some metadata annotation.

          It gets us the flexibility of being able to quickly return exactly the desired data, while retaining control over the queries and complexity.

      • sholladay 3 days ago

        A world where the front end can access any database field it wants sounds like a security / privacy nightmare to me.

        Of course there are ways to prevent data from being returned but that’s fragile.

        • netik 3 days ago

          This isn’t remotely a problem. Field by field granular security is trivial to implement in GraohQL

          • hamandcheese 3 days ago

            I have to disagree with you there. It is possible, but it causes other annoying problems.

            For example, field-level security pretty much means every field could be null at any time. Depending on your graphql server implementation, this might cause an entire request to fail rather than just that field to be omitted, unless you change your schema to where everything is nullable.

            Checking every field can also easily lead to performance issues, because it’s not uncommon for a large, complex graphql request to have hundreds or thousands of fields (particularly when displaying lists of data to a user).

            • withinboredom 3 days ago

              Not to mention GraphQL wasn’t designed with security and user-state in mind. It was an afterthought that was bolted on, varying from framework implementation to implementation.

              • jfengel 3 days ago

                How the heck was that not on their minds from day 1? It's the most obvious question to ask about a project like that.

                • necovek 2 days ago

                  GraphQL is mostly concerned with the query semantics.

                  A proper solution to security/privacy issues should have sensitive data never reach the outermost GraphQL layer.

                  So the problem is with the existing tooling that enables GraphQL implementations, but like anything else, if that tooling is deficient, the entire approach is on the shaky ground too.

                • withinboredom 2 days ago

                  It’s from before the https-everywhere days, or around the same time letsencrypt was started up, IIRC. Back then, I feel like security wasn’t as big of an issue, at least for less sensitive things. Like literally the entire site would be http until you got to checkout and the only reason you had the certs was to be PCI compliant.

            • dragon-hn 2 days ago

              > unless you change your schema to where everything is nullable

              At my current job, this was done before I was involved. It isn’t a deal breaker, but it throws away one of the best features of GraphQL.

              In the end you just have every client implement the rules that should have been in an API tier (if they are competent), or worse no validation that gets you a giant mess.

      • BerislavLopac 3 days ago

        Assuming the backend actually supports mapping of that particular field.

      • _3u10 3 days ago

        For external users of the API this can be quite helpful when you’re looking for the password column on the users table.

        For some reason I don’t think graphql actually works this way. Can’t quite put my finger on why allowing access to any column on a table might be a really bad idea.

        • HelloNurse 3 days ago

          Putting passwords in a database, and that database behind some kind of service that allows queries, is a stupid mistake that can be implemented with SOAP, CORBA, a remote shell, or any other protocol or API style.

          I don't think GraphQL makes the problem worse except by encouraging experimentation by putting an unusually powerful query language in the hands of the users

          • jonhohle 3 days ago

            Ancestors of your post are suggesting exposing entire DB schemas (I would assume mechanically). While that could also be the case in other protocols, typical an IDL is used to separately define the API layer. Of course it’s completely possible to generate a WSDL, etc. from a DB schema, in practice I’ve never seen it done.

            • HelloNurse 2 days ago

              My point is that passwords shouldn't be stored in the "normal" database where some clever architect might expose entire DB schemas to external access.

              If clever architects manage to expose the carefully segregated database of the small and secure authentication module, they cannot claim it was an accident or someone else's fault,

        • charcircuit 2 days ago

          >Can’t quite put my finger on why allowing access to any column on a table might be a really bad idea.

          Privacy

      • ahepp 3 days ago

        Why not just query the database directly then?

  • NeedMoreCowbell 3 days ago

    +1 This is it. Great for internal API's, not so much for public facing ones.

mabbo 3 days ago

Whether it was the intention or not, I find GraphQL solved a fascinating problem: it let front end developers move faster by greatly decoupling their data needs from the backend developers.

Backend developers describe the data model, expose it via graphql. Front end developers, often ones who never met those backend developers, can see the data model and just use it. They can change what they're querying on the fly, get more or less as they see fit.

It lets everyone move faster.

But as a backend developer, I actually fucking hate it, myself.

  • breckenedge 3 days ago

    I get specialization, but are there any other good reasons to divide product teams between frontend and backend? I guess it also helps establish patterns and contracts, but I think those are only helpful above a critical mass that I haven’t reached in my career yet.

    • TheAceOfHearts 3 days ago

      It depends on the kind of application and scale. Consider a large and complex application like Discord or Figma. Past a certain point, it's hard for anyone to know how every single detail works.

      You should probably be comfortable enough to work with both ends of the spectrum, but specialization allows you to do a much deeper dive into complex subjects.

      A backend engineer probably has a much deeper understanding of every little nuance of their prefered database. A great backend engineer can make sure that you're getting near-optimal performance from every important query.

      A frontend engineer probably knows about various UX techniques along with how to avoid unecessary reflows and repaints. A great frontend engineer can implement a UI toolkit as well as advanced techniques such as windowing.

      • breckenedge 3 days ago

        Right, that’s specialization. IMO those people still belong on the same feature implementation team for most organizations out there.

    • dasil003 3 days ago

      The reason is to scale teams. It’s not the only way to do it—you can also have vertical teams—but it’s a common one because frontend and backend have different technical considerations. The downside is the product can lose cohesion as developers get tunnel vision. Of course all big teams suffer from a version of that problem depending how the lines are drawn.

    • endisneigh 3 days ago

      In a small organization there isn't generally any reason to divide the teams between front and back end. As you've alluded - once you have many clients you'll want to separate responsibilities in order to increase velocity.

    • adra 3 days ago

      Frontend teams are often feature partitioned at least in larger orgs. There will need to be some level of feature level backend knowledge to be had somewhere, but backend problems are often feature agnostic. Many companies conflate backend with platform, which have subtle differences, but end up working with similar results. Specialized backend teams work to develop a really good "platform" feature while frontend teams focus on developing customer/product oriented features.

    • withinboredom 3 days ago

      This is something I’ve wondered as well. Coming from the military and occasionally working with spec-ops, I would say having a few “full stack” teams would be the way to go. I am just a lowly dev though, so what do I know?

      The separation of front/backend has always been mildly entertaining to me and I’ve worked on both teams. Btw, if you ever want to cause a political mess, just submit a PR to add a new API endpoint to the backend team that “doesn’t have the time” to work on it. Woah boy, they will get mighty pissed. As a backend engineer these days, it would be a blessing to get free work from another team… I don’t know why they were so pissed that one time.

      • krick 2 days ago

        Well, if you are truly wondering, I think I can give you some intuition about "why they were so pissed". Obviously, I don't know what were the facts of the situation, and if they really should've been pissed, but I can explain the typical mindset.

        The main idea is that writing some code to achieve any particular effect in the system is typically easy. But writing code, that is efficient and maintainable isn't easy. So, there's a team X, which has people working on some specific system. They own the code. To them, their work isn't quite about "implementing requested features". It is about inventing proper abstractions that both reflect the logic of the requested feature and reasonably anticipate the logic of any future feature requests. They want to avoid having 2 implementations of the same thing, they want every piece of code to be idiomatic to their system, etc. And they are right thinking like that, BTW. Every new developer they get is treated with some suspicion at first, and when he learns the idioms of the system he becomes a honored member of the team X. If he fails to learn them, he gets fired or passed to another team, where he may turn out a better fit.

        So, for the members of team X, they are professionals, who know how to work on the product and on the system X. Members of other back-end teams are probably not, even if they are good devs otherwise. Some frontend dev — doubly so. Some junior frontend dev coming from military or helpdesk or whatever — triply so.

        So, you may think that you are a great and charitable developer, who just implemented a Feature. But to them, you are a lowly ape who made a wobbly hut out of some sticks and leaves that is going to fall down now any moment, and it's going to fall down on THEIR heads (and you will be long gone).

        Worse than that, they understand, that other non-engineers (like their manager) also are prone to mistaking a wobbly hut for a Feature. And you basically humiliated them in front of these people by "solving" their problems (while in fact you created more problems). So it gets political here. In fact, because of that, even if the above is not a fair description of your work, they kind want it to be fair, they want you to fuck up, because it at least makes it easier to explain why your help wasn't a real help.

        And, in all fairness, it is kinda unlikely that a guy who is new to a codebase didn't fuck up in any way, even ever so slightly. Especially if that's a kind of guy who doesn't understand why dedicated back-end and front-end teams exist.

        • withinboredom 2 days ago

          > BTW. Every new developer they get is treated with some suspicion at first, and when he learns the idioms of the system he becomes a honored member of the team X. If he fails to learn them, he gets fired or passed to another team, where he may turn out a better fit.

          Oooh, that's an interesting observation. This was so long ago, before I really knew about this attitude. Since then, I've been on these teams and despise that attitude. I didn't even know that attitude existed back then, so this is indeed a possibility.

          > And, in all fairness, it is kinda unlikely that a guy who is new to a codebase didn't fuck up in any way, even ever so slightly. Especially if that's a kind of guy who doesn't understand why dedicated back-end and front-end teams exist.

          Hah, they couldn't find any fault with the code, the unit tests were even better quality than their own. I also submitted several other PRs fixing bugs that I discovered while writing unit tests. Their reason for not merging the code, after reviewing it, was that the implementation "didn't seem scalable" despite including performance tests showing that it was both faster and used less resources than some of the more popular API endpoints.

          When I joined, they kept having GC problems and I pointed out that they were using the Desktop GC method instead of the Server mode GC (this was C# 3.x?) and they didn't even know that that was a thing. They didn't like how some frontend engineer seemed to know more about C# than them.... I imagine that it was a combination of a lot of things, me knowing more about their language than them and not being on their team, plus submitting PRs "showing them up."

          This was my first time working at a company with more than 10 devs, so I was used to just getting shit done and not worrying about politics. These days, I know better.

      • NateEag 2 days ago

        They were likely pissed because they were afraid it would make them look bad to management - "How come no one on the backend team could find time to build this, but one front-end guy managed to despite his regular workload?"

        It's an easy conclusion to get to, whether justified or not.

        No one likes being made to look incompetent, regardless of whether they actually are.

        I have the impression you didn't ask for permission before you did it - the dynamic is wildly different if you start things off by asking if they'd be okay with you taking some time to build it, then involve them in your process as much or as little as they want.

        If that's what you actually did, then my analysis is way off.

    • pragmatic 3 days ago

      I think you are saying why not combine specialists on one team vs the “everyone is fullstack+devops” amateur hour dystopia that is becoming all too common?

      • ipaddr 3 days ago

        Back in the day we call this role Webmaster. Being able to manage your server, write your code and design the website was what a true developer tried to achieve.

        It is strange to see developers preferring to stay in their isolated environments and not wanting to touch the entire stack.

        • moonchrome 2 days ago

          It's not strange at all - it takes months of work to get productive with insert whatever tech stack here even when it's within your experience domain. Problem domains are really separate. Toolchains and languages are different. It's already hard to find people competent on one stack/field - hoping to find a team of competent "full-stack", in the broadest sense of the word, is probably prohibitively expensive.

        • electrondood 2 days ago

          This actually made sense back in the day. Now there's significantly more complexity for each part of the stack, tooling, distributed design patterns for scaling, etc. We don't really have "websites" any more, for example. We have apps that run in the browser.

      • Aeolun 2 days ago

        > the “everyone is fullstack+devops” amateur hour dystopia that is becoming all too common?

        What a weird thing to say. That was the original state. At some point people started splitting things up because they felt that would be better (or they just weren’t capable of grasping more than one thing?), but I’m extremely sceptical of all this specialization.

      • breckenedge 3 days ago

        I think we’re all amateurs at some part of the stack. I am not the CircleCI dude in my current gig, some other competent engineer is, but I’ve been the Jenkins dude in the past because I cared about it the most.

    • tveita 2 days ago

      You can have N frontends for one backend. If you need a new iOS app you will probably hire a team of iOS developers, not have all of your product teams learn Swift.

      If your API looks like this...

        /ios-app/v1/landing-page
        /android-app/v1/landing-page
        /android-app/v2/landing-page
        /windows-mobile/v1/landing-page (legacy)
        /web/v5/...
      
      where each platform has its own subtly different UI structure, the ability for frontend teams to get basically an arbitrary JSON structure of their choosing starts looking worth the extra work on the backend.

      You might not encounter this problem at any point that's fine - there are other ways to avoid it, like having a cross-platform codebase. I have "hand-rolled" similar solutions to the GraphQL field selection before, and I would use the GraphQL protocol if I were to do it again today.

      • robjan 2 days ago

        It could be the contrived example, but REST URIs are supposed to represent resources, not UI pages or elements. When the endpoints start to become coupled to the UI the backend can get messy, as you described, very quickly.

    • TedDoesntTalk 3 days ago

      > good reasons to divide product teams between frontend and backend?

      People specialize in different things. A great React developer may not be a great Java developer, and vice-versa

      • Aeolun 2 days ago

        An intermediate Java and React developer is more than the sum of the parts. Especially when considering a whole team.

        You may need one or two really great React and/or Java developers.

    • satyrnein 3 days ago

      From a management perspective, the fiction of the full stack developer that is equally skilled at everything is the easiest. You stick with that until you complicate your architecture (wisely or not) to the point where having specialists outweighs having to manage multiples queues of work and dependencies.

      • ant1oz 3 days ago

        Worse approach imo.

        Nowadays a full stack dev is an intermediate Fe dev, with junior backend skills. He will make your backend un-maintainable. Get a proper master on a proper contract rate to design your architecture.

  • jayd16 3 days ago

    To me it's a weird way to go about this decoupling. Another way is you can just keep your own view-model client side and abstract the backend data with that.

    FFBs and GraphQL is a way to tightly couple to a backend system and then have that backend system loosely coupled.

    I guess its all 6 of one, half-dozen of the other, but I usually prefer to just handle things client side. You can maybe get less data transfer optimization but that's down the road from the fast development stage, anyway.

  • NonNefarious 3 days ago

    I thought it was supposed to do this, but then discovered that it has no way to express joins.

    Has this been addressed? I don't see how you can decouple the back-end data from front-end queries without that.

    • vikR0001 3 days ago

      You can do something like this. This query can be created and run on the client:

      ``` const SAMPLE_JOIN_QUERY = gql` query ($main_data_id: String!) { mainData( main_data_id: $main_data_id) { id main_data_field_1 main_data_field_2 main_data_field_3 related_data{ related_data_field_1 related_data_field_2 related_data_field_3 } } } `; ```

      • mdaniel 3 days ago

        https://news.ycombinator.com/formatdoc may interest you

            const SAMPLE_JOIN_QUERY = gql`
            query ($main_data_id: String!) {
              mainData( main_data_id: $main_data_id) { 
                id main_data_field_1 main_data_field_2 main_data_field_3 
                related_data {
                  related_data_field_1 related_data_field_2 related_data_field_3
                }
              } 
            }`;
      • platz 3 days ago

        in other words, it's up to the folks writing the resolvers to manifest and implement that join as a nested field.

        • mst 3 days ago

          Which means a lot of the time they end up just caching as hard as they can and hoping that's good enough.

          (which is often, honestly, an entirely rational decision in terms of prioritising limited resources, but still makes me sad)

      • initplus 2 days ago

        Right, but on the backend someone had to think ahead of time that somebody would want to JOIN between those two types, and remember to put the field in place, and implement the JOIN.

  • grumple 3 days ago

    Curious as to why you hate it specifically. Because what you could be doing is exposing every table / field automatically based on permissions (which you could set up a system where you don't even have to be involved).

    • toolz 3 days ago

      because either the boilerplate is massive or the libraries do so much for you that you have to specialize in understanding the libraries magic - front-end plus back-end code for graphql is almost always more than a traditional REST api and I mean a lot more code, not just a bit more, so more code is strongly correlated with more problems. The exception is when you use heavy libraries that have magical APIs. Then you end up with teams who understand the API and have no idea how graphql actually works, which is probably an even worse problem.

      • mattbillenstein 3 days ago

        What tooling are you using that requires a massive amount of extra code? You need to define the schema and write resolvers, but that's sorta similar to what you might do in REST on the backend.

        On the frontend, you have a choice to use some of the heavier libraries that support all of the features (like subscriptions) - but otherwise, you can just POST a gql query to the server and it will return a blob of json, which really isn't so much more than REST.

        • initplus 2 days ago

          Why use graphql at all if you are going to use it just like a traditional REST api? You don't get much of a benefit from the client selecting which fields it wants, the backend probably fetches the entire DB row anyway so why not just send the whole thing over?

          The limitations of the query language make code size explode the moment you step outside simple toy examples. It doesn't have any concept of a JOIN, or of the actual relationships between your types (graphql has no concept that me == me.parent.child). You end up writing data loaders for every type so that loops in your schema can be resolved efficiently.

          Managing permissions is so much more of a pain compared to REST because exactly what data is returned is so much more dynamic. If you have some confidential data nested 10 layers deep in the query, you get two choices. Either fail the entire query with a NotAllowed based on one deeply nested field that the client maybe does not even care about, or you have to make your schema super loose and make every single field that's subject to permission management nullable. So much easier on a REST endpoint because the response is more constrained.

          • grumple 2 days ago

            You use graphql when you have many consumers of your data, whether other teams at your company or external data partners (which is how my team uses it). What it does is make it so that you don't have to provide a bunch of custom endpoints for these users, they can get exactly what they need without your help. You're also able to get performance gains dependent on the implementation.

            Our code size for our graphql endpoint has remained totally unchanged for the past couple of years. It took only a few files (of admittedly complex code) to automatically set it up so that it would automatically provide all models via the graphql schema (and a separate permissions implementation restricts access at each level of the schema). It updates automatically whenever we add new models or permissions. This is built on top of Rails and the graphql gem.

    • mabbo 3 days ago

      Honestly it's mostly just lack of familiarity, which is getting better every day.

  • quickthrower2 3 days ago

    It sounds like it is promoting a siloed cogs in the machine type of work ethic. Where you are either front end or back end and no one is thinking end-to-end about the system.

    • satyrnein 3 days ago

      I think the causality runs the other way. Once the frontend had gotten so complex that it required a specialized team, solutions arose to reduce the back and forth necessary between frontend and backend teams.

    • adra 3 days ago

      Sr enough developers who's role expands beyond a single team, architects, product managers, product owners, the list goes on for the roles of people who are often task of thinking big picture about the health and "end-to-end" picture of any given software project. Your narrow synicism makes me assume you don't work in a company that has a large dev org. People specialize and if you want to be the learn and do everything person, you'll find that you're doing less and learning more which isn't a good fit for most orgs.

      • quickthrower2 2 days ago

        You are right I have worked in relatively small companies (and "bigger small" companies that were not doing web).

        My concern is not specialization which I think is necessary for a larger company. It is more the technical solution of "here is GraphQL now your teams don't need to talk and you don't need anyone thinking end to end". I can't believe that is helpful.

        I may have created a strawman though?

    • locutous 3 days ago

      That's generally true for sizable companies. Small companies can and do use full stack devs.

      Segmentation makes some sense but the industry is lacking end to end thinking as you point out.

  • mattbillenstein 3 days ago

    Why do you hate it? What tooling are you using? I found it fairly painless in Python - Graphene/Flask.

    • matsemann 3 days ago

      If all you do is expose simple models, it's fine. But then not much different than an auto-generated REST-api. But if you want to query deep, list of childrens etc you quickly get into queries that are very hard to write on the backend (n+1 issues quickly pop up etc). To solve those you need to write complicated loaders, which all should be very general in nature and thus you can't rely on two fields backed by the same data sharing a query without doing something special. Which is much more hassle than just writing whatever join you want for a tailored endpoint.

      • mattbillenstein a day ago

        The N query is the general case which devolves to the scaler query with a list of ids with only one id...

    • mabbo 2 days ago

      I joke mostly. Coming from a REST based background it was really foreign and convoluted to me.

      Until I understood the point, the organizational decoupling. Then it clicked why it's great.

gloosx 27 minutes ago

GraphQL is amazing. It always lame to see someone using wrong tools for tasks, even in carpentry. Same here of course, it's not bad, they just try to plane boards with saws, and you blame the saws

thdxr 3 days ago

Be careful with anyone with a take that says some technology is 100% bad always. Given enough experience / skill you can make any technology fairly enjoyable so I've only ever seen mixed reactions at worst from people giving things a fair try.

GraphQL is a way to describe not only your API but also the entities and relationships in it. This enables certain useful things for client heavy applications, like cache normalization. If you look at clients like URQL they enable high quality features in your app that are otherwise extremely difficult.

You can also do this with JSONAPI but the GraphQL ecosystem is more developed.

Setting up GraphQL to minimize its rough edges is incredibly difficult. I've currently landed on a combination of Pothos + Genql + URQL to enable me to do everything in typescript instead of untyped strings.

It takes very high skill to use GraphQL well. Few teams get there because they don't have the upfront time to do all the research.

But if you pull it off it can be an incredibly productive system that is friendly to iteration and refactoring. I can send you some content we've produced on this if you're interested.

That said, if I'm not working on a client heavy app, I'd just use a less featureful RPC framework.

  • eduction 3 days ago

    > Be careful with anyone with a take that says some technology is 100% bad always.

    This isn’t that though; the first sentence starts “GraphQL is great, but” and then the post lists first “the good” and then “the bad.” Even the provocative headline hedges with “kinda.”

    I wish there was more of this sort of balanced discussion on HN. There is a tendency among devs at least in public toward trying to get others to use the tech they use and are excited about, which is understandable, but everything involves trade offs and it would be nice to hear more of those up front (as opposed to one day “mongo is the bomb” and the next “actually mongo is terrible to back to postgres for everything).

    • thdxr 3 days ago

      was referring to some of the replies

      • eduction 3 days ago

        Ah ok I definitely misunderstood, thanks for clarifying.

    • minusf 3 days ago

      > balanced discussion

      while the discussion can be balanced the real world outcome is normally binary: use it or drop it.

      i will not start investing huge amounts of time to learn graphql if it has very specific use cases for specific environments. so i naturally look for red flags and objectively negative experiences to see if those might be the roadblocks i would run into 2 months down the line.

      imagine a PM coming in all happy "i know nothing about graphql besides the hype but i think it's a great fit for our next project". where will balanced discussion take you there?

  • lf-non 3 days ago

    Agree with everything here, but something that often gets missed is that you don't have to use all that GraphQL enables from day one.

    It is perfectly fine to start with an early implementation that treats GraphQL as mostly an RPC, with only resolvers for Query & Mutation types. You still benefit from GraphQL's type-safety, batching and code-generation.

    Once you have more familiarity with dataloaders, query complexity etc. update your output objects to have links to other output objects building the graph model.

    The issue is that too many people get fascinated with GraphQL early, then build deep & complex topologies and expose it in inefficient and potentially insecure way.

  • mccorrinall 3 days ago

    I love consuming graphql as a client. But writing resolvers and all that stuff on the backend? God, I hate it!

    • kubami 2 days ago

      It's very enjoyable with python. Especially given integrations with frameworks like django.

    • adra 3 days ago

      I don't know your language of choice, but in the JVM ecosystem, Netflix DGS is so damn simple to build new resolvers.

    • nawgz 3 days ago

      Hasura :)

      • ant1oz 3 days ago

        Have you every tried to version your permissions on Hasura? Not cool. Product polish is amazing, and I love the postgresql integration.

        • cpursley 3 days ago

          Interesting point. What sort of approaches out there do you know about for versioning permissions?

        • nawgz 2 days ago

          Nope, I haven't, here's hoping I won't need to!

          First time thinking about the situation, sounds to me like you'd need to just make a new set of roles no? I can't imagine they'd have version support for that, not like the underlying datastore does

  • PainfullyNormal 3 days ago

    > Be careful with anyone with a take that says some technology is 100% bad always.

    On the flip side, you should also be careful of anyone who says some technology is 100% good always. It's far more common to see people talking up the advantages of some trendy new technology without ever mentioning the downsides. All technologies have tradeoffs.

  • chpmrc 3 days ago

    > Be careful with anyone with a take that says some technology is 100% bad always.

    THIS 100%.

    > It takes very high skill to use GraphQL well. But if you pull it off it can be an incredibly productive system that is friendly to integration and refactoring.

    I could not agree more. It's like any other piece of tech: once you internalize the mental model and are able to translate those abstractions in your language of choice everything clicks. And then it's hard to imagine going back to something more "primitive" (i.e. what's conventionally called "REST").

    After building "RESTful" APIs for years I can confidently say GraphQL (with a decent implementation) is a step up across almost every possible dimension (performance aside because of the additional parsing).

    • necovek 2 days ago

      > It's like any other piece of tech: once you internalize the mental model and are able to translate those abstractions in your language of choice everything clicks.

      While this is true, I think the ultimate assesment of a technology is how easy is it for someone skilled at doing similar work to internalize the model and abstractions.

      A tech stack can become really successful only if this is easy and relatively quick, otherwise, it will meet a lot of resistance. Partly because it's hard to master, but partly because so many people will be misusing it (which makes an even bigger annoyance for someone who's trying to get to a proper mental model).

      As such, I've come to appreciate only models that majority of developers can easily get right on the first go: or rather, models which are hard to get wrong.

    • throwawaymaths 2 days ago

      Eh I think "rest for external API access, graphql for internal frontend use" is probably a good thing.

  • endisneigh 3 days ago

    > Be careful with anyone with a take that says some technology is 100% bad always. Given enough experience / skill you can make any technology fairly enjoyable so I've only ever seen mixed reactions at worse from people giving things a fair try.

    Completely agreed. Without knowing the team experience, greenfield project or not or in general more information about the task at hand, how can anyone say GraphQL is good or not?

    One thing I've noticed among some people who've failed to move up in their career is that they carry these extreme opinions due to a proper understanding or a bad experience. Right tool for the job and all that.

  • meesterdude 3 days ago

    > Given enough experience / skill you can make any technology fairly enjoyable

    Have you never used MongoDB?

    • thdxr 3 days ago
      • mst 3 days ago

        The other thing to note is that early on the default configuration was optimised to score really well on trivial benchmarks rather than production workloads - including having important safety features turned off.

        A crashing MongoDB instance in default configuration was more likely to lose data irrevocably than a MySQL 3.23 MyISAM setup.

        (note that while I still don't particularly enjoy using it, post-WiredTiger MongoDB is a different story so take this as a criticism of the people making choices in the early days, not at all of the current state of affairs)

      • Kaze404 3 days ago

        That’s a great thread. It mimics my (admittedly limited) experience with MongoDB and it’s interesting to hear that wasn’t an outlier.

  • deltasevennine 3 days ago

    >Be careful with anyone with a take that says some technology is 100% bad always. Given enough experience / skill you can make any technology fairly enjoyable so I've only ever seen mixed reactions at worst from people giving things a fair try.

    So what does this mean?

    You're saying that in the universe we live in there is absolutely nothing that is 100% bad always. Everything is good for something? There is no concept of bad or obsolete things because it's all good for something?

    Let's restrict this to programming languages and frameworks and apis.

    Are you saying that in the universe of ALL programming languages, ALL frameworks and all APIs, None of them are at all bad and they are all good for something?

    I don't agree with this sentiment at all. In fact I think it's a sign of two possibilities:

    1. that the person saying it is highly biased and unable to detect things that are genuinely bad.

    2. The person saying it is just being temporarily illogical, there are clearly things in the programming world that are bad. He knows this but is so biased that he's incapable of processing this concept while promoting his favorite language/api/framework.

    Scenario 2 is the most likely scenario here. Not saying graphQL is bad. But to love graphQL so much as to say Nothing in the universe is actually bad?

    Let's be real, I am not against graphQL. However you cannot actually say that people against graphQL have invalid opinions because there is nothing in the programming universe that is definitively bad. This argument does not make any sense at all.

    • Kaze404 3 days ago

      The point is that “bad” isn’t a useful descriptor of anything regarding their real-life applications, because it simply doesn’t mean anything. Without more context, saying something is bad is just saying you dislike it with intent to present it as objective rather than subjective.

      For example:

      1) “Haskell is bad because it’s too theoretical” 2) “Haskell is bad in corporate environments, as its roots in mathematical and academia make it harder for people to get productive with it compared to something like Java or C#”

      The difference is clear. In my opinion it’s best if people who care about what they’re saying avoids #1, and instead frames their criticism like in #2.

      Note: those examples don’t reflect my actual opinion on Haskell, it’s just something I came up with while writing this.

      • deltasevennine 3 days ago

        Hard disagree.

        >The point is that “bad” isn’t a useful descriptor of anything regarding their real-life applications, because it simply doesn’t mean anything.

        This is just a complicated way of saying "Bad things have no meaning and don't exist in the universe."

        Without getting too pedantic, in general, nobody agrees with this concept. Sure if you get pedantic you may find a couple people in this world who enjoy punching themselves in the face, but in general the overwhelming majority agree that punching yourself in the face is a pretty bad thing.

        Note: Punching yourself in the face is just an example of a universally "bad" thing. I'm not personally against punching yourself in the face, it's just something I came up with while writing this.

        • Kaze404 3 days ago

          Maybe I failed to express myself properly, but my point is that saying “X is bad.” (emphasis on the period) is not really saying anything. It’s much more productive if you explain why, how and in what environment X is bad, either before or after, like I did in example #2.

          In my experience when someone says “X is bad”, the response is often either “haha” (which the subject then changes), or “why” (which leads to person #1 actually saying what they want to say). I’m personally not interested in someone’s remarks about some technology completely devoid of context or nuance, and would rather hear about their opinion on such technology in tangible scenarios.

          • deltasevennine 3 days ago

            >Maybe I failed to express myself properly, but my point is that saying “X is bad.” (emphasis on the period) is not really saying anything.

            This logic also works for "X is good." or "GraphQL is good". This doesn't really say anything either and is an equally garbage statement following your logic. But your biases focus on the "bad" because you have a bias towards GraphQL.

            Either way I don't agree. Saying something like criminals are bad is not an invalid statement.

            If you want an explanation you can ask for it. If you don't care to know about the explanation then you don't need to ask for it. But just because somebody makes a statement without an explanation doesn't automatically make it invalid.

            For example "The plane is about to crash, please pull up." This is a statement without an explanation (emphasis on the period). Should I demand an explanation or comply without one? In your words, was this statement "really saying anything?" Yes it was.

            When you come to threads on HN it's mostly people looking for confirmation of their biases. They don't realize it, but almost everyone is doing this. If you weren't biased you would ask for deeper explanations. You would try to unravel the other persons reasoning and understand it in such a way so that you find a mistake in his understanding or your own. That's mainly why I'm here, but this thread is littered with posts following the same logical path as you.

            • Kaze404 2 days ago

              There are way too many assumptions in your post. Yes, you're right that I like GraphQL, but:

              1) Nowhere in my comments did I say that's limited to negative comments. I think "GraphQL is good" is just as useful (meaning not at all).

              2) "Criminals are bad" is not an invalid statement, and neither is "GraphQL is bad" or "GraphQL" is good. But if the purpose is to discuss criminality, and not just add noise to an ongoing discussion, it is also a useless statement. Imagine there's a debate panel going on, someone in the crowd stands up and says "criminals are bad!". Where does that lead the conversation?

              3) "The plane is about to crash, please pull up" is an expression of fact, not an opinion, and not even something that warrants or is said in a discussion so I don't think the comparison makes sense. Either way, "GraphQL is bad" is an opinion, not a fact, and thus needs more context to be useful in a discussion.

              I'm not going to acknowledge the last paragraph because I'm presuming good faith from you, and I'd rather not turn this discussion into speculation about other comments in this thread or why you're here.

              That said, you're definitely right that I'm biased towards GraphQL, but I think we're having different discussions if you think we're discussing GraphQL's merits.

              • deltasevennine 2 days ago

                >Where does that lead the conversation?

                It's not about leading the conversation some place. He's under no obligation to lead the conversation to a place you want it to go. If someone says something different, I don't dismiss the statement. I follow up with a question. You didn't. YOu simply made a broad statement dismissing all queries saying "X is bad" as invalid and you think it's up to the person stating something to explain. No. If you want an explanation you ask for it. But the statement by itself isn't invalid.

                However you completely dismissing the negative claim was invalid in my opinion.

                >But if the purpose is to discuss criminality,

                Obviously this is an example not a segway into criminal law. I am showing an example of a statement that is true independent of explanation. True statements are not to be ignored even when they lack explanations. That is the point.

                >"The plane is about to crash, please pull up" is an expression of fact, not an opinion, and not even something that warrants or is said in a discussion so I don't think the comparison makes sense

                You can't automatically say something is a fact. It's very possible things like this are an expression of opinion. The copilot observes sensor readings, he thinks we're about to crash. The pilot observes sensor readings he see's no such indication of an impending crash. This is a realistic possibility. The ounter to this is also true. You may assume GraphQL being bad is an opinion, but it's possible that it is a fact.

                Let me elaborate on that. What if the person who hates GraphQL is actually expressing a universal fact? But like the pilot you have a differing opinion because you "misread" the sensor readings. Instead of taking the cautionary approach of pulling up and subsequently listening to the copilots reasoning you dismiss a statement because it has no explanation.

                The point of this example is to show you a very obvious scenario where it's highly unwise to dismiss a possibly True statement simply because it lacked an explanation. That is my point. You are dismissing a statement that has the possibility of being factually true. And you are saying you don't care whether or not it's true or not if the statement has not auto generated explanation you will dismiss it instead of inquiring further.

                >I'm not going to acknowledge the last paragraph because I'm presuming good faith from you, and I'd rather not turn this discussion into speculation about other comments in this thread or why you're here.

                fine. The point of me bringing it up is to not make this seem like a personal attack. But to frame my reply as a universal problem among all proponents of GraphQL that are responding in this thread. Basically i'm just reading people Gushing about how great GraphQL is and not exactly addressing why it's also despised by many on HN.

                >That said, you're definitely right that I'm biased towards GraphQL, but I think we're having different discussions if you think we're discussing GraphQL's merits.

                We aren't, not explicitly. I'm a neutral party with no opinion either way, I'm here to find a side to join. However reading your post and seeing that you're a proponent of GraphQL I'm criticizing your reasoning as unconvincing. Basically, Someone said GraphQL was bad, and your reasoning was all statements of the query "X is bad" should be dismissed.

                I responded to explain to you why I didn't find your reasoning valid. That's all.

Guid_NewGuid 3 days ago

Hmm, I feel weird reading all this criticism of GQL. It reminds me of when our place switched to it and I was constantly slagging it off until my friend/colleague said "do you actually hate it or you just don't understand it?".

Default hostility to new concepts and frameworks can save a lot of time, energy and mistakes in software but sometimes for some use cases the new (variation of an old) solution can be superior.

We use it as the API we expose for our React and mobile clients and it's just, so good. I'd never want to consume it for a non-FE client but it's night and day versus stitching the results of multiple API calls together using some godawful chunk of mess like Redux.

We have a C# backend and Typescript frontend. We write our backend resolvers of the form `public async Task<SomeResultType> GetSomeNamedField(TypedParams pq)` and it just works, Apollo generates type safe client code and we define the schema in a single place. We still write backend code to implement each resolver method, exactly how we did in a normal API but... that's just the same.

I wonder how bad other backend devx must be for all these people to hate it, it seems more like a language specific implementation flaw than a genuine problem.

  • jddil 3 days ago

    You haven't actually described any of the unique parts of GraphQL though. Generating a typesafe API whose schema is defined in a single place is trivial with an OpenApi spec and a client generator

    What I've noticed is people get their first taste of a type safe api and automatic client creation via GraphQL and don't understand that exists without it.

    • MisterSandman 3 days ago

      > What I've noticed is people get their first taste of a type safe api and automatic client creation via GraphQL and don't understand that exists without it.

      I mean, yes, you can technically write any project in C if you're smart and dedicated enough, but data scientists still use Python because it's easier to work with for the things they need to do. The fact that GraphQL is inherently safe, while REST is inherently not, is why people like GraphQL. OpenAPI is hardly the standard in Rest APIs.

      • zelphirkalt 2 days ago

        I think it is the other way around. REST inherently only offers, what routes you implement, nothing more. In that sense it is "safe". There are frameworks like "Rocket" in Rust, which make things typesafe from the moment a request arrives at your route's handler. While GraphQL requires you to implement who can access what, because you allow the frontend a lot of freedom to formulate queries. This is inherently unsafe.

        Perhaps we are talking about different kinds of "safety" or "aspects of safety"?

aleclm 3 days ago

We recently had to design an HTTP API, and we wanted to have as much automatic stuff as possible. I mean:

* Autogenerated documentation

* Autogenerated wrappers for scripting languages

* Autogenerated validator for requests and responses

For a REST API, you can get most of these things with swagger or stuff like that, but clearly it's an afterthought. If you have a schema, it's all much more natural and elegant.

But the most important thing you get with GraphQL is batching. For our use case (a decompilation pipeline) if you make 10 requests one after the other or 10 requests altogether it makes a huge difference in terms of performance.

If you need batching and design a REST API, for every nice endpoint you have you need to make a bulk version of the API. You're likely going to do that POST'ing a JSON. Now, once you're at that point, you're reinventing the wheel with six sides.

If your backend is in C/C++ and I suggest to make a C API for Python and use ariadne:

    https://ariadnegraphql.org/
Don't do GraphQL in C/C++.
  • loosescrews 3 days ago

    > But the most important thing you get with GraphQL is batching.

    Doesn't HTTP/2 make this mostly obsolete? One of its big features is request multiplexing.

    Regarding the auto-generated code bit, are auto-generated GraphQL clients a thing? It seems like it would be doable, but I haven't found any (at least for the languages I'm using).

    • aleclm a day ago

      > Doesn't HTTP/2 make this mostly obsolete? One of its big features is request multiplexing.

      HTTP/2 helps with the network layer, but your backend will still handle requests one-by-one. Depending on what you need to do, this might make a hell of a difference.

      > Regarding the auto-generated code bit, are auto-generated GraphQL clients a thing? It seems like it would be doable, but I haven't found any (at least for the languages I'm using).

      There's this:

          https://www.graphql-code-generator.com/
      
      But yeah, on a second look I expected to find more. Anyway, having a standard way to do things instead of relying on one specific piece coupled to some language (swagger), it's certainly better. On the other hand REST APIs have a much longer history, so I guess it's normal for them to have more tools.
    • kortex 3 days ago

      I believe by batching they mean operating on collections of entities instead of single ones. So you may have POST /pets to create a single pet from a json object, but what if you want to add a hundred pets at once? Even with multiplexing, this is often way less efficient. Often the solution is to have POST /pets/bulk which takes a list of objects.

      • nogridbag 3 days ago

        I suppose it depends on the domain, but in all the APIs I've created bulk operations are fairly rare. I guess if you know upfront that your API would involve heavy bulk operations then seeking a tool that makes that more performant would be beneficial.

cletus 3 days ago

My usual experiene is that people use GraphQL wrong. GraphQL's primary use case is to homogenize access to a bunch of heteregenous backend services. If you find yourself just taking your Postgres database and creating a 1:1 mapping between your tables and GraphQL, this probably isn't a good fit as you'r ejust adding another layer for no reason.

> No clear path for Api versioning

GraphQL came about as a way for mobile clients to call backend services. At Facebook, once a version (of th emobile app) was released, it was essentially out there forever. Some people would simply never upgrade until they absolutely had to.

So the point of GraphQL is that you want to get away from thinking about versioning your API and cleanly upgrading because you probably can't. You can do versions but you don't have clean divisions. You'll mark a given field as "since v2.1". And fields that you ahve added can basically never be removed. The best you can do is make them return null or an error.

So if you want to do versions it probably means you have control over the server and the client such that you can deploy them almost simultaneously. If so, GraphQL isn't really designed for your use case. If not, get out of the mindset that client and server versions can move in lockstep.

I will say I think GraphQL made one mistake and that's baking in string values into the API. You can't change a field name without breaking your API. Same with enum values.

Protocol buffers (including gRPC) instead went for numbering. The name is just a convenience for reading the IDL and data definitions and for code generation but it doesn't translate to the wire format at all.

This can have downsides too but they're fairly minimal. For example, if you accidentally renumber your enums by inserting a new value in the middle, the whole thing can break (side note: always explicitly number your enum values in protobuf! That should've been the only way to do it).

Another issue is that fragments seem like a good idea for code reuse but they can get really out of hand. It's so much easier just to add a field to an existing fragment. If that fragment is used in a bunch of places you may find yourself regenerating a ton of code. You will never be able to remove that field from the fragment once added.

Disclaimer: Ex-Facebooker.

  • nchase 2 days ago

    > GraphQL came about as a way for mobile clients to call backend services. At Facebook, once a version (of the mobile app) was released, it was essentially out there forever. Some people would simply never upgrade until they absolutely had to. > > The point of GraphQL is that you want to get away from thinking about versioning your API and cleanly upgrading because you probably can't. You can do versions but you don't have clean divisions. You'll mark a given field as "since v2.1". And fields that you have added can basically never be removed. The best you can do is make them return null or an error.

    This nails it. For distributed apps where a client might never be updated, you can't really change your schema if you want to guarantee that your app works for everyone. You can build in a mechanism to prompt users to update to a later version, though, and that can be very effective.

  • hamandcheese 3 days ago

    My company has many backends federated together, but a monolithic, web-based frontend. It’s actually really easy to remove a field from graphql.

    1. Remove all uses from the frontend. 2. Deploy. 3. A day later, delete it from the schema.

    If deleting it causes relay compiler errors, go back to step 1.

    (The less lazy way to do it would be to actually pull some stats about how long-lived frontend bundles are)

    Not being able to delete fields only really applies if you have a huge number of clients that you can’t easily force to update on a whim. Plenty of folks just have web clients.

    My company doesn’t have this, but I’d love to get per-field usage stats about our schema.

    • cletus 3 days ago

      That affirms my point: you have complete control over the front end.

jongjong 3 days ago

Some other bad things:

- Makes caching more challenging since there are now more possible permutations of the data depending on what query the client uses. A hacker could just spam your server's memory with cache entries by crafting many variations of queries.

- Makes access control a lot more complicated, slower and error-prone since the query needs to be analyzed in order to determine which resources are involved in any specific query in order for the server to decide whether to allow or block access to a resource. It's not like in REST where the request tells you exactly and precisely what resource the client wants to access.

- Adds overhead on the server side. It requires additional resources to process a query rather than just fetching resources by ID or fetching simple lists of resources. A lot of work may need to happen behind the scenes to fulfill a query and GraphQL hides this from the developer; this can lead to inefficient queries being used. I have a similar complaint about database ORMs which generate complex queries behind the scenes; this makes it difficult to identify performance issues in the underlying queries (since these are often completely hidden from the developer). Hiding necessary complexity is not a good idea... Maybe worse than adding unnecessary complexity.

  • krschultz 3 days ago

    It shifts the complexity to the server side. The additional logic you are describing currently lives on the client, where it's harder to update and likely duplicative across platforms.

  • ojkelly 2 days ago

    You can cache the objects in the query by ID. And then reuse them across a number of queries.

    > It's not like in REST where the request tells you exactly and precisely what resource the client wants to access.

    It can be. You can have a query that does `getObject(id: $id): Object`.

    > Adds overhead on the server side.

    Yep it pulls a heap of complexity around data fetching, synchronisation, and data modelling from the client to the server.

    As it requires both the client and server to come to some agreement about a shared data model, it can appear as more work up front. But it enables a decoupling of the client and server such that the client can make requests for new use cases with the existing shared data model.

  • endisneigh 3 days ago

    > - Makes caching more challenging since there are now more possible permutations of the data depending on what query the client uses. A hacker could just spam your server's memory with cache entries by crafting many variations of queries.

    You could use something like https://stellate.co/.

    > - Makes access control a lot more complicated, slower and error-prone since the query needs to be analyzed in order to determine which resources are involved in any specific query in order for the server to decide whether to allow or block access to a resource.

    Hasura and Postgraphile can do this - in the case of Postgraphile it obviously requires Postgres.

    • the_mitsuhiko 3 days ago

      If the solution for caching problems turns out to be a hosted API proxy then there are still not enough tools available. If you put some third party infrastructure in front of your API then your availability is exactly that company's availability.

blacklight 2 days ago

We're forgetting an elephant in the room. REST APIs make it easy to cache data. Do a GET /api/objects/123, and if the object hasn't changed since last time we'll hit the cache. You can't do that with GraphQL, because a URL doesn't descrive a single resource.

What I like doing is to create a REST layer that sits just on top of the database, and a GraphQL layer on top of it that allows all kind of fancy queries. Yes, HTTP is slow and multiple calls for a single request should be avoided if possible. But it's much easier to run server-to-server HTTP calls (especially if the servers live in the same DC or physical machine) than running client-to-server requests.

cersa8 3 days ago

I use GraphQL (postgraphile) for my admin backend crud. This allowed me to do some incredible fast development with only minimal customisation (couple of PostgreSQL functions). Anything outside the happy path is handled by a REST API. Maybe we shouldn't think in absolutes, eg: only use GraphQL. For the same reasons I use an ORM, and raw queries where it matters most. The cliché holds true: use the right tool for the job.

dmitryminkovsky 3 days ago

Some nits:

> It doesn't support map/tables/dictionaries. This is actually huge. I get that there might be

It does. You can define, say, an "any" or "json" type in your schema and emit anything you want at a field with such a type. For example https://stackoverflow.com/a/63588485

> No clear path for Api versioning

Some options include:

- Prefixes (`/v1/graphql`, `/v2/graphql`)

- Backward compatibility: only adding and not subtracting things you want to support.

Lots of fair criticisms though. My two cents:

There are very few cases for starting a GraphQL based project by writing a GraphQL server (resolvers, queries, etc). This is where devs waste time instead of exploring their concepts. Instead, use GraphQL with something like Hasura that generates the GraphQL service for you based on database schema.

  • ojkelly 2 days ago

    > Instead, use GraphQL with something like Hasura that generates the GraphQL service for you based on database schema.

    I generally disagree. While Hasura and the like can get you moving quickly, they let you cheat on designing your data model.

    Ideally it’s a collaboration between all involved to develop a shared understanding of the domain, and the queries and mutations (how to read and write).

    Where possible avoiding implementation details leaking into the schema will let you change those implementation details when needed.

    If you auto-generate from a database, your database itself becomes your schema. This is rarely the best way to represent your data model in an API.

philliphaydon 3 days ago

> It can save you bandwidth. Get what you ask for and no more

I feel like this a false truth.

Most people are building a web app, or a mobile app and consuming an api and displaying all the data they retrieve.

If you have an rest api which returns an object with 6 properties. And a graphQl scheme which returns those same 6 properties. You’re not saving anything.

Now if you have a website and a mobile app, where the mobile app needs 3 fields and the website needs 6 fields. You will obviously save on bandwidth with the mobile app.

The problem here is most of us are not building Facebook. The data saved is peanuts and the bandwidth cost is probably going to be far less than the total cost of doing the work to support graphql.

For a company like Facebook which has many different integrations as well as 3rd parties integrating, graphql is obviously a godsend as integrators and integrations can consume only what they require and save Facebook millions of dollars in bandwidth.

  • krschultz 3 days ago

    Every company I've worked for in the last 10 years had multiple apps across several platforms, each with many versions, all running in production at once. Even if you only care about the next version you are shipping and a handful in production that's a dozen variations.

    In a REST paradigm you over fetch because not all of these variations need the same data, or you send less but then the clients thicker because they merge API calls and have divergent presentation logic, or you have a bajillion API versions.

    There's often a lot of back and forth between the various teams for each rev of the API.

    GraphQL lets the clients drive the definition of the data fetching. That's it.

    95% of the criticism of GraphQL is people complaining that GraphQL doesn't solve the problem of preparing the API response for these different requests. While that's true, that's not what it's supposed to provide. Whether you have a REST API with 26 versions or a GraphQL API with 26 variations of query you're going to have to write a backend-for-frontend style service that resolves the results.

    GraphQL just standardizes this process.

    • chronofar 3 days ago

      > 95% of the criticism of GraphQL is people complaining that GraphQL doesn't solve the problem of preparing the API response for these different requests.

      This problem is solved by quite a few GraphQL providers nowadays. Hasura, DGraph (not true graphql but close enough), Prisma. I like Hasura quite a lot for many projects. Just define your database and you instantly have a full GQL API for the clients to use however they please, no backend required really. Doesn’t work for everything, but it’s pretty great for a wide swath of projects.

  • grumple 3 days ago

    > If you have an rest api which returns an object with 6 properties. And a graphQl scheme which returns those same 6 properties. You’re not saving anything.

    You aren't thinking big enough. We have a graphql API where we have a bunch of enterprise users all wanting to pull out different types of data. They can decide what they want to get, and pull exactly that data. They want access to different tables, fields, and for different purposes and with different filters. We don't have to be involved, we just give them the schema.

    • vsareto 3 days ago

      I guess it works, but it still seems like an extra step compared to giving them DB access unless they're in some weird place where they can learn to use GraphQL but not Sql/NoSql

      • grumple 2 days ago

        The issue is we don't want them having direct db access. Aside from multitenency, permissions, and configuration issues (all solved by graphql) they could easily bring down a database instance (avoided via limits we impose via our server). If we didn't have multitenancy then it wouldn't be a problem.

        But there's also the issue that some presentation and business logic is also provided by the graphql schema. Graphql knows which nodes connect, the db itself doesn't. And special cases like overrides, formatting, etc can be handled by the graphql server.

    • philliphaydon 3 days ago

      > We have a graphql API where we have a bunch of enterprise users all wanting to pull out different types of data.

      That’s a great use for graphql. My issue is toooo many people are building web apps with graphql where they are the only consumer. They are not getting any of the benefits of graphql, especially bandwidth savings.

      If you have many people integrating and you in vision the types of integrations needing very different queries for data then graphql is great.

      But most companies are a website, maybe some mobile stuff, and not enough traffic to warrant the complexity or benefits of graphql.

  • gitgud 2 days ago

    > If you have an rest API which returns an object with 6 properties. And a graphQl scheme which returns those same 6 properties. You’re not saving anything.

    Not entirely true, as it allows you schemas to scale, but your requests to remain small.

    For example a "User" record might have 30 fields, and it might have more as the system evolves. But your requests that only specify "User First name" will remain the same size.

rglover 3 days ago

Having spent several years working with GraphQL (using it in multiple projects and teaching it to others), I've found that in the majority of cases just doing a plain JSON-RPC API is preferable and far easier to reason about for all skill levels.

When I built Joystick [1], this is why I implemented the API system [2] as a JSON-RPC model, but stole the idea of validating inputs (optionally) and then on the client, optionally specifying tailored output (also optional—like how you can request specific fields back in GraphQL but instead of a custom query language, just pass an array of paths like ['customers.creditCard.expirationMonth', 'customers.creditCard.expirationYear'] for the specific data you want returned).

What I learned implementing that is that the typing/querying for specific fields ideas is brilliant, but much better when it's flexible (i.e., I want it sometimes but not all the time).

[1] https://github.com/cheatcode/joystick

[2] https://github.com/cheatcode/joystick#api-1

scottwick 3 days ago

GraphQL is nice from a consumer's perspective but results in a lot of extra complexity on the backend IMO. It sounds nice in theory for the frontend to just request whatever it needs but there are often performance considerations that make this easier said than done. You end up either tailoring the database queries for particular GraphQL queries (i.e. eager loading certain things you know will be fetched) or implementing some sort of more generic dataloader pattern. The fields and data types become more explicit through the schema but there are still implicit access patterns in play. Definitely a tradeoff vs. a REST API where each endpoint can be highly optimized since you know exactly what's being returned.

OJFord 2 days ago

You forgot number 1: '200 your graphql request succeeded, here are all your errors'.

...I get it, the gql request did succeed, I've previously described it as like a 'layer 8' on top of HTTP: the problem being that all the tooling is for HTTP.

I wish 'REST' was one thing - with generated OpenAPI servers/clients & 'links' for example we could achieve what gql sets out to, if only there was a single way to do it.

  • ojkelly 2 days ago

    Your request could be fulfilled by multiple services, some of which may have errors.

    Building on this are result types, where you can return a union with the intended type and something like AccessDenied for specific fields a user does have access to, but some other user might. Here you start to model the happy and unhappy paths of the data model.

    GraphQL itself doesn’t really say anything about the network layer, it sits above that, in the application layer. You can run your queries and mutations over a websocket connection, at which point 200/4xx/5xx don’t make sense.

    • OJFord 2 days ago

      Like I said, I get it. (And fwiw '200/4xx/5xx' also sit in the application layer, just HTTP not GraphQL, which is why I described it as like a 'layer 8' (a fictional one above application) over HTTP.) It's just not a good 'DX'.

  • OrangeMusic 21 hours ago

    > 200 your graphql request succeeded, here are all your errors

    I'm not sure how that's a problem? The client knows where to look for errors: not in the http response code but in the JSON payload. Why is that an issue?

  • initplus 2 days ago

    Our monitoring says all the requests are 200 OK, why is the client down?

OmarIsmail 3 days ago

Yes, graphql does indeed suck. Or rather it is not the best solution for all client-server communication that people treat it as, so it ends up being used in a lot of situations where it does suck.

Backend to backend communication is almost never graphql (is that changing in a big way?) which would indicate the main reason for graphql in a client-server situation is data saving but at the cost of complexity and other downsides. Almost certainly the data savings in many cases is not worth it.

Oh and then you have things like Apollo having cache bugs that result in incident level problems.

  • eurasiantiger 3 days ago

    Does Apollo really have cache bugs? Usually it’s the data itself which doesn’t have a unique id field, or the client hasn’t been configured to know about the proper id field.

    Granted, it’s a problem to have to do that. But such is life with entity-level caching.

0x20cowboy 3 days ago

If you have one sever with one end point, and never use other services, graphql doesn’t make sense. Don’t use it.

If you work with a bunch of Micro services, and you’re only a backend developer, you likely don’t understand the problem graphql is solving. The alternatives are almost always way worse.

> No clear path for Api versioning you'll end up with MyQueryV1.01 MyQueryV1.02 MyQueryV1.03

You’re not supposed to version it. That’s what the @deprecation is for.

> It is actually a pain to use, depending on the backend you are using you'll have to manage

Do some front end work, or use your companies API as a client. Something where you have to talk to several services and try to stitch together some sort of combined data with all the latency and unreliability of http over a cell phone network. Then pontificate about how the boundaries between the services are wrong, but never change anything - or better yet change a bunch of boundaries then change the UI to cross different boundaries - then complain about how the UI should always have to exactly match your services because the world should revolve around how you’ve decided to see the problem.

Yikes, where did that come from. That wasn’t directed at you.

Don’t use graphql. When you figure out what it’s for, it’ll be easier to learn.

vlod 3 days ago

> It can save you bandwidth. Get what you ask for and no more

On the other hand, you tend to do "select * from FOO" and get more data from the db, because you don't know what the caller will ask for.

I don't think I've even seen a codebase filter the SQL based on the caller. I think I tried doing it once and it was a pita. (Please correct me if it's easy).

  • coder543 3 days ago

    The typical approach that I've seen is to do "select * from FOO" for simple scalar fields that cost very little to retrieve from the database. If you have any fields that often contain large amounts of data, or any relations, you can provide a separate resolver for that field or relation, and then that resolver will only get invoked if the caller requested it. It's pretty straightforward, at least when using Apollo and TypeScript. (Obviously you would modify the original query to exclude such expensive fields so that you’re not duplicating work with the additional resolver.)

    I still don't think I would personally recommend GraphQL to most companies.

geuis 3 days ago

It's not an unpopular opinion: it's true. Graphql is a terrible piece of software/paradigm.

I've completely avoided it for years. If a potential new job contacts me and they use graphql, it's an immediate no from me. It's an immediate red flag that the engineering culture at the company is poorly run and would be a nightmare to work in.

Run away, as fast as possible.

  • hn_throwaway_99 3 days ago

    > It's an immediate red flag that the engineering culture at the company is poorly run and would be a nightmare to work in.

    Well, at least I'm glad I know I'll never be working with you!

    I'm not giving you shit because you don't like GraphQL, I'm giving you shit because of your asinine "if you use GraphQL your company is poorly run and a nightmare" comment.

    Whenever I see a comment from any developer that says "If you use technology X then you are an idiot", then I know that developer is either incredibly junior and doesn't understand the tradeoffs in choosing any technology, or they're showing typical "if you don't like what I like than you don't know what you're doing" arrogance that inevitably always makes it a pain in the ass to work with that person.

    • NonNefarious 3 days ago

      Yep. I worked at a place that fired almost its entire programming staff because they insisted on using Visual C++ to build a CRUD app, while a team of contractors built a prototype in Visual Basic.

      Needless to say, the VB app worked fine and became the product.

      • diarrhea 3 days ago

        If you don't mind, would you explain this more? I don't understand the implications; VB does sound "worse" than Visual C++ for such a job, from an outsider perspective?

        • CRConrad 18 hours ago

          > VB does sound "worse" than Visual C++ for such a job

          Huh? No no, on the contrary: Straightforward CRUD apps, that's exactly what VB was built for and excels at. Only Delphi is better.

          The thing about "Visual" C++ is that it isn't (or at least wasn't, last I looked) really very visual at all. And that sucks for building simple in-house CRUD apps, where the VB / Delphi drag-and-drop UI builder paradigm is a huge productivity multiplier.

        • koonsolo 3 days ago

          In C++ you have to manage your own memory. Why would you want to do that when you're simply pushing data around.

          I wouldn't choose VB myself, but when it's between VB and C++ for simple data pushing, I would indeed choose VB.

          Let's say it like this: if you need to move stuff, would you choose a F1 car or a minivan. I would pick the minivan.

        • NonNefarious 3 days ago

          No problem. At the time, Visual C++ lacked several important OCX controls that were included with VB, so they had to be hand-coded.

          If you were building an application that does little more than populate forms with data from a database and then update the database, VB was totally adequate. The most important part of the job was the DB and query design.

      • mechanical_bear 3 days ago

        Why is this “needless to say”, as if it should be apparent to anyone?

        • NonNefarious 3 days ago

          Because a CRUD app doesn't require any serious computing performance from the application, making C++ unnecessary. If another implementation won the race to functional completion, then... needless to say... it was the one to go with.

          Today you'd probably just use browser-based UI.

          Also if you've spent time in corporate development (rather than a software company), I think this scenario is a common one. If you show management a prototype that works, they're going to ask why we don't just make that the product. And if you don't have a good reason... you don't have a good reason.

    • spywaregorilla 3 days ago

      I felt pretty confident about my conclusions of my first dusty old bank job that used a custom shittier homebrew of google web toolkit and no source control.

      • hn_throwaway_99 3 days ago

        But that's very different. "No source control" means they aren't following or don't understand the very basics of software process management. That's very different from "If you use SCM system X, Y or Z you're an idiot."

        • spywaregorilla 3 days ago

          Email and the windows file system is a SCM system if you're dumb enough.

    • cudgy 3 days ago

      You are right that this arrogant attitude is juvenile, but it is prevalent amongst humans in all areas. Unfortunately, there would be few developers to work with if you apply the policy of not working with arrogant, dogmatic developers.

      • hn_throwaway_99 3 days ago

        Strongly disagree, primarily because when this type of attitude infects dev teams it is usually a cultural issue, not an individual one.

        The primary, inviolable value I have, and look for, in dev teams is "strong opinions, loosely held". Meaning I want to work with engineers that have the experience, motivation and intelligence to have strong opinions about how things should be done, but it's also critically important that developers are humble enough to know other developers may have other experiences that can inform why a different decision can be better.

        If you've worked in a dev team that embodies this attitude, you know how great it can be and how dev team members will naturally work to strongly defend the group dynamic that it fosters. Meaning if a developer with a bit too much arrogance joins the team, they can often be trained into not having to be so judgemental, or making disagreements about real issues and not emotional arguments ("GraphQL sucks and you're stupid if you use it") If not, the existing team will quickly reject that arrogant developer because they know how dangerous they can be to a healthy group dynamic.

        • CRConrad 15 hours ago

          > look for, in dev teams is "strong opinions, loosely held".

          Rather strong opinions, not super-strongly held.

          If you know you're somewhat flexible in your opinion, it's going to be quite strong, but not all that strong. OTOH, if you have an even somewhat strong opinion, it's no use letting yourself be swayed from it all that easily; make them advance quite a good argument for it first.

          But then, depending on how heavily you load your adjectives, maybe that's what your (admittedly much more pithily put) version meant, too. I just wanted to put the modifiers out there lest someone read the maxim at its strongest.

      • ttfkam 3 days ago

        I'm truly saddened to hear that this has been your experience throughout your career so far. It is not a universal experience. I hope you find a better managed shop soon that recognizes that it's easier to teach folks a tech stack than to teach someone to be a decent (or honest) person.

        Too many tech shops sabotage their culture and dozens of potentially great contributors in order to keep a few (or one) toxic contributors that the powers that be erroneously believe are irreplaceable.

        Anyone can be a 10x developer when you sabotage the well-being and productivity of those around you.

        • ant1oz 3 days ago

          Well said. I would also add that it is perfectly fine to have a list of red flags, and it is perfect fine to define your own bondaries. Graphql is a red flag for me too, as well is React and node.js, and even git to some extend. I love simplicity when designing web apps, their backend, their frontend and the deployment process in between. Although the tech is old , I came up that vue3+pouchdb+quasar is an amazing combination for a stable replicable dev environment, pwa, supports offline usage, and introduces possible p2p replication between browser's pouchdb instances trough webrtc.

          React , imo, is a good over engineered library suffering from fragmentation. Angular is less fragmented, and Vue is the most elegant, performant and versatile of the 3. Good Devs choose Vue after having worked with both react and angular. React Dev never tried Vue, nor Angular Dev try React. Vue Dev usually know all 3.

          Having a red flag like graphql can tell a lot about technical overview and experience in failure.

          Graphql solves a caching issue that Facebook has. Makes the frontend team life easy, making the backend team life hell , big big hello. Scope changes in the backend are terrible.

          Unless your team is engineered driven, and engineers take tech decision, and setup the sprints, going graphql in the backend is a recipe for disaster.

          • ttfkam 2 days ago

            This is like hating HTTP. GraphQL is a spec, not an implementation. GraphQL doesn't even mandate a network transport.

            Solutions like Prisma, Hasura, and Postgraphile make GraphQL dead simple to implement compared to REST when exposing relational data.

            AWS AppSync allows for a fully managed "serverless" experience as long as you're willing to do the schema creation grunt work and write Velocity templates. (FWIW, I'm not a fan, but it's still an option.)

            Apollo (and Netflix DGS) are for when you're writing everything yourself, and you just need a simple API to tie in to the GraphQL spec in exchange for having to write/optimize/maintain it all.

            The bright side to GraphQL is that you have choices, and when you present your "menu" of options, clients can grab what they need. Whereas on the REST side, any new requirements in calling requires direct interaction with the backend team and a new endpoint.

            Honestly, server-based data access doesn't get any simpler than Postgraphile, but I totally see how you could get burned by an ill-fitting solution. However that is not GraphQL's fault. You might as well blame HTTP for problems you've had with Node/Express even though you've got other options in every programming language not to mention "pre-baked" solutions like Apache, Nginx, etc.

            It's just a spec defining interaction, not a prescription for how that spec is implemented. It is also not a silver bullet. Right tool, right job, and all of that.

      • Kaze404 3 days ago

        There’s this stereotype of a programmer, that while I think can be funny sometimes, still reflects a professional that doesn’t really exist anymore from my perspective.

        Most software engineers I’ve worked with have been incredibly humble and dedicated. The mythical bearded guy that showers three times a day, comes to the office with shorts and flip flops, and refuses to install Windows on the accountant person’s machine because it’s objectively bad is something I’ve only seen in memes and stories from older people I’ve worked with.

        I personally think dissolving this myth, along with the one that programming is easy and / or none of us know what we’re doing, should be a shared goal between people who care about what they do and how others perceive it. Otherwise we’re unknowingly cultivating it into existence, and I definitely don’t want to work with arrogant, dogmatic developers.

      • koonsolo 3 days ago

        For me it signals maturity.

        When it's a junior, I remember myself and think they still need to learn.

        When it's a senior, I know it's not a senior.

  • chpmrc 3 days ago

    > Graphql is a terrible piece of software/paradigm.

    Says who, exactly? What data are you basing this on? Or is it a completely subjective opinion dictated by frustration likely caused by the lack of understanding of it?

    • runald 3 days ago

      Did you try reading the thread? What do you mean by data?

      > Or is it a completely subjective opinion dictated by frustration likely caused by the lack of understanding of it?

      You can ask this this very same question when people say graphql is an amazing piece of software/paradigm, except s/frustration/hype/

      • chpmrc 3 days ago

        Your argument stops being valid the second you realize that a lot of devs who use GraphQL started out as skeptics (e.g. me), then spent time actually understanding its nuances before coming to a conclusion for a specific project/team.

        And, in general, there's no such thing as a "good" or a "bad" technology, there are dimensions and each dimension is a spectrum: utility, adoption, availability, cost, complexity (although hard to determine), etc. to compress all that down to "hype" or "it sucks" just show how little time has been spent on understanding the nuances I mentioned above.

        I don't claim GraphQL is amazing or even good, it just proved to be a great way to build APIs for the projects I worked on. I'm sure someone who builds firmwares for embedded automated plumbing systems would disagree (within that context). If you decide not to adopt it I just hope you do it after a rational, unbiased review of what the tech is capable of and what the shortcomings are, rather than "oh it's over hyped".

        > Did you try reading the thread? What do you mean by data?

        Please don't question whether someone read the thread or not (which is irrelevant within the scope of this discussion anyway) just because they disagree with you.

  • eknkc 3 days ago

    So you are sure that some tech that you avoided completely (and I assume have zero experience in) is a terrible piece of software.

    Great. What is your take on the postal service structure of Turkmenistan btw?

    • mechanical_bear 3 days ago

      Their service scope is waaaay too broad, no reason to be responsible for quasi banking services, traffic fine payment, and utility payment processing.

      • CRConrad 15 hours ago

        Services like those are part of the scope of quite a lot of national post institutions, and actually for quite valid reasons.

  • soccersofia15 3 days ago

    Based on your logic, you’ve never worked for Airbnb, Uber, Facebook, Twitter, etc… which is also funny cause they have fantastic engineering culture. What a strange way to filter yourself out of great engineering companies just because of a piece of technology

    • minusf 2 days ago

      doesnt matter how beautiful the engineering culture/talented the pool if it works on ads/surveillance/facebook.

  • zmxz 3 days ago

    Yup, gotta trust the words from some unknown from internet, with 0 proof. As if we're all there, up in your head, able to hear every single thought you have and determine that what you say is pure, unfiltered truth.

    If many manage to use GraphQL and be content with it, that should be an indicator to you. But, you chose it isn't and that you'll merely display how politely negative you can be.

    Thank you.

    • runald 3 days ago

      > trust the words

      > pure, unfiltered truth

      noone is forcing anyone to believe in anything, it's just some guy expressing his strong opinions about a subject, but no, you act like someone uttered a blasphemy against the lord's name

  • publicdaniel 3 days ago

    It’s not an unpopular opinion on HackerNews.

lofatdairy 3 days ago

From what I've read GraphQL makes the most sense in the context of large scale teams and large databases. It introduces a large amount of overhead to your backend to parse queries, but allows those queries to be more flexible and not think about the database's schema which is a tremendous boon when you get to the scale where communication between teams is more expensive than implementation time. For junior and midlevel devs watching youtubes and reading blogs it's obviously an exciting technology because of what it promises (in this sense GraphQL is hardly unique), but there's a practical cost to production workloads.

That said, if I'm not mistaken GraphQL is almost explicitly designed with a versionless paradigm in mind. Whether or not that's a good decision is up for debate, but it's less "no clear path" and more like it's the responsibility of the backend to add support for new access patterns without causing old patterns to fail.

  • NegativeLatency 3 days ago

    Some libraries offer enterprise features for versioning.

    Like you said it makes sense in larger companies. As a consumer of a well documented API it’s great, as someone who had to stitch together 2 microservices to provide the required data it sucks.

sonthonax 3 days ago

GraphQL seems to be one of those 'bootcamp technologies'. I see it being advertised as a skill a bootcamp teaches more than I've ever seen used. I can imagine that for a junior developer the endless freedom might be quite paralysising.

What I don't understand about GraphQL, is that the majority of data people deal with is simple and relational. It's rare enough to have a deep (more than 4 layers) relational data structure that needs to be queried at once. And usually those data structures are relational to ever smaller relations; think user->company->address->country->county. Solving this with GraphQL just seems a bit bizarre when you can write a view of this data.

Maybe though, it owes its popularity in bootcamps because it allows unqualified developer to forget about writing the query layer.

  • sibeliuss 3 days ago

    With GraphQL you are making a view of your data. You're using types to describe an idealized API response. It's a frontend and it can do anything you want.

  • jahewson 3 days ago

    You’re right! You don’t understand GraphQL.

gabereiser 3 days ago

I tried graphql in a microservices environment and had huge headaches over schema stitching.

Turns out, if you have lots of objects from disparate sources, graphql don’t like that. Now you must stitch these schemas together into an über schema roll query and use with graphql. Maybe we missed a step. Maybe we misunderstood. Maybe it was a bad decision.

  • soccersofia15 3 days ago

    Same! We’ve been using WunderGraph to help with schema stitching and integrating other data sources

  • locutous 3 days ago

    I used graphql at one place and our stitching was a disaster. I'm thinking bad decision.

    We also had micro services. It was the most unstable backend I've ever worked with.

    Yet the architects who picked all these techs were mostly lauded and didn't stick around to deal with the mess.

  • PUSH_AX 3 days ago

    And good luck doing that in a language that isn’t JS. All our GQL services were Go, but were forced to use JS for any stitching needs.

hn_user145 3 days ago

In any fast paced business, APIs constantly change. Versioning is not straightforward. Often corners are cut, and deadlines have to be met. There just is one version of the API, the one in production!

In my experience the most pain around GraphQL was due to a lack of care/time. Too often schemas are not strictly defined, are too generic (type: any) and fields are not documented. Errors are poorly defined etc. Combine that with untyped code, it's almost the same as sending blobs of arbitrary JSON around. In the short term it works, the feature is live, business is happy. But takes double the effort to untangle the code when you need to change something....

GraphQL also requires effort to make tooling and monitoring work well with it as it deviates from a traditional REST like model.

  • yellow_lead 3 days ago

    > There just is one version of the API, the one in production!

    Unless there are multiple in production, i.e /v1/api, /v2/api, etc

datalopers 3 days ago

GraphQL's primary feature is enabling data exfiltration for bad actors

  • x86x87 3 days ago

    This nails it. Had the "proviledge" of needing to secure a GQL endpoint and it's a mess. AuthZ? What's that? + Runaway queries that kill the database? check! + Caching? Lol.

    Setting aside security and scalabilty for a second: Ifeel like GQL is at its best a complicated database driver, with the data types being defined and implemented twice: once in the DB layes, once in the backed.

    • adra 3 days ago

      If you're testing gql as anything remotely similar to a database facade, you've already lost. GQL is meant to provide functionality that generally happens to be data backed. If you want to push all your work to the frontend and treat gql as a db shim, you're solving the wrong problem in the wrong ways.

      • x86x87 17 hours ago

        That's a lot of words, but what does it mean? What does "generally happens to be data backed" means? Are you suggesting that GQL add value in the transforms that it's creating? In how is glueing together multiple types of data?

alerighi 3 days ago

To me is not that great either. I find it simpler and more robust a well designed REST API, where with well designed I mean that the semantic of the methods is respected and it works on resources.

The thing is that GraphQL is an RPC mechanism, contrary to REST that is a protocol to do CRUD operations on resources, and that has all the complexity associated with an RPC itself.

bigmattystyles 2 days ago

I've asked before and I've never got a straight answer, but why isn't ODATA more popular? It's open, though I know SAP and MS have botched their ecosystem mostly via inaction. But to me, it's great, SQL -> ORM -> ODATA, for 95% of what I need, it fits perfectly.

jwr 3 days ago

"Very Senior Dev" here (though it amuses me to call myself that). I had managed to avoid GraphQL for a while, but recently had to actually look at it and use it. I was appalled that in this day and age, this hyped silver bullet basically requires me to build queries using strings.

I was honestly surprised by this: when I first heard about the idea behind GraphQL, I was certain that I'd pass in nested data structures.

I use it because I have to (external services jumped on the hype bandwagon), but I don't consider it significant progress. And this "save bandwidth" advantage is totally oversold, I really can't see how the savings can be significant in a practical way.

  • chpmrc 3 days ago

    > I was appalled that in this day and age, this hyped silver bullet basically requires me to build queries using strings.

    That's like saying SQL is crap because you need to build queries by hand. Conflating a protocol/spec with its implementation and/or the way it's used is not something a "very senior dev" should do (not questioning you personally, just the validity of what you wrote in this specific comment).

    There are plenty of good GraphQL libraries that make writing queries/mutations and the whole schema a breeze. I've been using graphene for Python for a couple of years and, although it has some rough edges, it's actually pretty decent. And GraphQL is quite a good mental model to work with that both backend and frontend can share.

    <rant>Honestly I'm getting tired of seeing these comments on HN, it's the same for Kubernetes or other technologies. Often written by someone who didn't take the time to actually study and understand the tech and use it for actual projects. Often with no data to back it up whatsoever. The quality of posts and comments here used to be a lot higher but it's slowly turning into a plaintext version of dev.to </rant>

    • spion 3 days ago

      The GP is right. GraphQL is especially annoying because it looks so close to JS/JSON, yet since no thought was put into how it might integrate into existing typed languages its actually surprisingly difficult to build a type-safe API around it.

      And yes, SQL is "bad" because you write query strings. The funny bit is that GraphQL may be just as hard to model in a type-safe way as SQL is, if not a little harder. At least with SQL we have a reasonably good way to model it with methods (see LINQ). LINQ was built 15 years ago, so this problem was well understood back then.

      • chpmrc 3 days ago

        > yet since no thought was put into how it might integrate into existing typed languages [...]

        Says who?

        > [...] its actually surprisingly difficult to build a type-safe API around it.

        Again, says who? The consumers of the APIs I work on are mostly written in Typescript and constructing types based on the GraphQL schema is a completely automated process. Are you telling me that it's easier to build type safe APIs based on examples of what JSON each endpoint might output?

        > And yes, SQL is "bad" because you write query strings

        Ok then every single language is bad because every language's syntax is based on (conceptually) constructing strings. I don't get your point.

        • spion 3 days ago

          > Says who?

          Says me, and also any other person that has tried to build a type-safe GraphQL query builder

          > Consumers of the APIs I work on are mostly written in Typescript and constructing types based on the GraphQL schema is a completely automated process

          Constructing "types" of what kind, and in what way? Types for queries? Do you need to rerun the tool every time you modify any of your queries? Does it need to watch your query strings to generate the right types for them?

          > Ok then every single language is bad because every language's syntax is based on (conceptually) constructing strings. I don't get your point.

          Instead of arguing, why not look at what LINQ does?

          For the best experience, you should probably try them with an editor/compiler: https://github.com/dotnet/try-samples#basics

          • chpmrc 2 days ago

            I'm not familiar with LINQ and even though it might be a good solution we're not debating GraphQL vs LINQ (which, as far as I can tell, is specific to C#, at least its reference implementation), I'm questioning your "string is bad" statement which, IMHO, doesn't make any sense.

          • valenterry 2 days ago

            It would be helpful if you actually explain how LINQ does it better.

            • spion 2 days ago

              LINQ lets you write SQL queries using the (.NET) language in which you write all your other code. This means you get to take full advantage of the language (and language service) features, including the typechecker, code completion etc.

              Examples: https://www.c-sharpcorner.com/article/writing-complex-querie...

              The hard bit here is making sure the language type-checker is fully aware of the involved types, both while writing the query as well as while selecting the results to be returned

              This approach has since been copied in more capable languages. One of my favorite examples lately is Rust's Diesel: https://diesel.rs/ (see the "complex queries") example.

              A query language designer aware of the above lessons learned with SQL might take special care to ensure their new query language is easier to model in existing languages. For example, they might consider an alternative OOP or FP based syntax, or to generalize they might put some thought into what would make it easy to write a type-safe query builder. After all, while SQL was developed in 197x and we had a different model for data access early on (stored procedures instead of flexible language-integrated queries) so its easier to understand that we didn't consider integration with other languags. TypeScript already did exist when GraphQL first appeared in 2015, and it's been 7 years of LINQ at that point.

              Yet, we still went the stored procedures route. Tools such as graphql-codegen [1] require you to regenerate your types every time you edit your query strings

              [1]: https://www.graphql-code-generator.com/

              • chpmrc 2 days ago

                This is just a wrapper for SQL, every language has one. The same is true for GraphQL, I've never written a GraphQL scema or query by hand, always used a good wrapper that handled all the type safety I needed. Constructing GQL queries manually is the equivalent of doing it with SQL.

                At this point I'm pretty sure you're conflating the underlying technology with what a wrapper could do on top of it. And in that regard I absolutely agree with you: raw GraphQL doesn't make any sense, the same way raw SQL (in 2022) doesn't make sense either.

                EDIT (mandatory before I get lynched lol): except in cases where the wrapper builds a query that is inefficient or should be tweaked manually.

                • spion 2 days ago

                  > I've never written a GraphQL scema or query by hand, always used a good wrapper

                  Could you give me an example of a good client wrapper that doesn't require you to write queries as strings?

                  • valenterry 2 days ago

                    Not sure if you consider it "good" but I've used this one quite successfully: https://ghostdogpr.github.io/caliban/docs/client.html#query-...

                    • spion a day ago

                      Its a reasonable looking wrapper. Could benefit from the ability to build queries with variables, although not sure if that would be useful in the Scala ecosystem.

                      To make it clear, I disagree I'm conflating things. I'm currently working on a TypeScript based graphql builder (https://typed-graphql-builder.spion.dev/) and I can think of several ways the language could've been designed to make it easier to write typed query builders.

                      This is not without consequences - since its quite hard to write the builder, most tools available for code generation (https://www.graphql-code-generator.com/) are built around editing GraphQL strings and will try to find them in your code and add type assertions. Additionally the rest of the ecosystem tools are built around supporting this workflow (graphql playgrund, etc)

                      • chpmrc 12 hours ago

                        > I can think of several ways the language could've been designed to make it easier to write typed query builders.

                        Would you like to share them? Have you tried submitting your suggestions to the GraphQL core team?

    • endisneigh 3 days ago

      Yeah, if you use something like Postgres and Hasura for a new project it's pretty simple. I doubt you could make a REST API much easier. Django + Django Admin is close, but that's not really an equivalent per se.

    • jwr 3 days ago

      > That's like saying SQL is crap because you need to build queries by hand

      If we want to use these terms, then SQL is indeed crap, because you need put query parameters in-band instead of out-of-band. This led to numerous exploits over the years, as it's difficult to ensure the data is correctly escaped. GraphQL just repeated the same mistakes.

      • chpmrc 3 days ago

        Calling SQL crap just because there's a way to abuse it is like saying C is crap because I could do `int * userGuess = get_number_from_user(); * userGuess;` with nothing more than a compiler warning (if I'm lucky).

        Would be nice if we all stopped with these blanket statements and just focused on evaluating individual pros/cons of things.

        EDIT: formatting of pointer

    • oznog 3 days ago

      > The quality of posts and comments here used to be a lot higher but it's slowly turning into a [..]

      You can go on with your GraphQL, Kubernetes, gigantic frameworks, and pages with 3MB of JS if you want.

      And let's see what stands the test of time.

      • chpmrc 3 days ago

        Well, GraphQL aside I've been using the same stack for almost ten years and it's only becoming more and more popular so I'd say I'm doing pretty well in terms of choosing the tech, thanks for your concern though!

  • spion 3 days ago

    Agreed. I'm working on a typed query builder for GraphQL and TS but secretly I'm a little mad that nobody gave some thought to making it easier to integrate in a type-safe way at least in the client languages

    https://github.com/typed-graphql-builder/typed-graphql-build...

    No docs yet, that's WIP

    • eurasiantiger 3 days ago

      It looks like a lot more boilerplate than normal GraphQL queries.

      • spion 3 days ago

        Not sure what you mean, I added the expected resulting GraphQL queries and they're about the same size. They aren't really normal queries, because I'm trying to exercise all of the features at once in the tests :)

  • eurasiantiger 3 days ago

    Hmm, there’s really nothing preventing you from writing a library which allows you to pass a data skeleton to an async function and get a full body back.

jeroenhd 3 days ago

My problem with GraphQL: it doesn't support generics.

I'm fine with request batching/complexity overloads/all that craziness. Most GraphQL libraries have some kind of protection mechanism in there, or allow you to artificially split up the request and forward it to your application load balancer.

I'm also fine with a lack of API versioning, especially for internal services.

Hell, I'll even tolerate the lack of dictionaries/maps because you can replicate the same data interchange by putting the key in the object you're requesting most of the time.

What I really want is to do not have to write a custom pagination wrapper type every time I write an API. Let me write a Paginated<T> that contains a list of T and some metadata, dammit! I don't want to dump BookPaginated/PagePaginated/AuthorPaginated into different schemas!

Another thing that bothers me is how types extending an interface need to have each and every field repeated. If I declare interface Car with wheels: Int! then I don't want to have to specify wheels: Int! again inside SportsCar. Any kind of inheritance creates giant schemas and adding new types to the super type means you have to re-insert the same parameter a million times.

Combined with a well-integrated ORM, GraphQL can have serious performance improvements over REST and similar so I definitely prefer it for big applications, but there are so many things that annoy me to no end.

  • csnweb 3 days ago

    I think you may be should give a code first GraphQL a try, you can pretty much everything you want that way. You can write high level functions for pagination or whatever that way and have a base object that you can extend for all Types implementing the interface. I really don’t know why schema first seems to be the default, it’s really unflexible.

    • andrewingram 2 days ago

      Strawberry (a GraphQL lib for Python) actually supports using generics to define types, it’s often used for supporting repetitive structures like pagination.

cube2222 3 days ago

Having had experience with it from a "backend for the frontend" perspective, GraphQL is nice because it gives you an API for free and does partly decouple the frontend team.

At the same time, with most backend GraphQL frameworks the decoupling will be very illusory, as in practice you'll have to tune the backend to the frontend use cases or you'll just end up with a ton of N+1 queries and terrible performance.

In other words, application-specific http endpoints have their advantages and let you have fine tuned queries for each use case, which makes sense for app-style frontends.

kehrin 3 days ago

> It doesn't support map/tables/dictionaries.

I don't understand this point. Is this talking about implementing GraphQL on the backend? Because consuming GraphQL you get a map, you get JSON! Do you mean a more specific data structures like a Set or Stack?

  • nawgz 3 days ago

    I think they were complaining that you couldn’t get back a query with unknown keys like a “select * from my_table” GQL equivalent

    • kehrin 3 days ago

      But can't you? During development I had this with errors, where I just enter "error" as a key in my query, but the actual data was JSON. So it had keys that I didn't specify, but that I received non-the-less.

      • nawgz 2 days ago

        It's true there's nothing in the spec preventing from returning that kind of thing, for instance a JSONB column in your underlying RDBMS would probably lead to what you describe, but it's more that when using SQL you can make "anonymous" queries where you say "give me all columns, I'll deal with their names myself", while GQL is more like "give me all these keys" and there's no way to not specify the key. I don't have great language tools to speak precisely here, hope it makes sense.

    • drcode 3 days ago

      That also doesn't make sense: No matter what, you're going to have to parse the returned document linearly, everything in it is therefore equivalent to a list in performance.

      Random-access structures like dictionaries, hashmaps make no sense in this context: It would be stupid if you had to do extra work to tell graphql what your preferred key parameter(s) are so that it can create a dictionary, and then you get list-like performance anyway.

  • the_mitsuhiko 3 days ago

    GraphQL has no native map type which means if you have a map data structure you cannot represent it within the type system.

mrbonner 19 hours ago

I’m evaluating Graphql for my service at this time. This service could be public facing in the future. A majority of the complaints about it that I learn in this post is about accidentally making your GraphQL’s nested graph structure an exploit.

What do you think if I just use graphql for the typed schema, flex return objects without the “graph” part? Or at least I would have a very shallow graph without nested data structure. Do you think it would help in this case?

SZJX 2 days ago

My experience with GraphQL has been with Absinthe in Elixir and it has been great. Custom REST endpoints can spiral into an inflexible mess with way too specialized DB queries built for each endpoint, while with GQL you can stitch different resources together on the frontend easily in one go. Of course, if you’re not careful you may get into N+1 issues, but there are solutions such as Dataloaders. Avoiding malicious queries sounds like a potential issue but as some comments have also pointed out, there are mitigations similar to e.g. rate limiting you also have to do on REST endpoints anyways.

replygirl 3 days ago

> It is actually a pain to use, depending on the backend you are using you'll have to manage two or more type systems if there are no code first generates in your language

hasn't been a problem for years in the ts, python, and .net communities

> It doesn't support map/tables/dictionaries. This is actually huge. I get that there might be some pattern where you don't want to allow this but for the majority of situations working with json api's you'll end up with a {[key: string] : T} somewhere

unions, embedded types, and custom resolvers, OR better api design

> No clear path for Api versioning you'll end up with MyQueryV1.01 MyQueryV1.02 MyQueryV1.03

this one is actually insane. /api/v1/graphql. sounds like you are new to apis

---

all of the complaints i hear about graphql have come from people who are early in the process of learning it and/or have built up faulty assumptions through malpractice

  • initplus 2 days ago

    In a traditional REST api I can version each resource independently. I can make a breaking change to just one type and it affects that type alone. Graphql is inherently less flexible in this respect as I have to version the entire API together as a single unit.

    Graphql itself has no concept of versioning so I need to go out of my way to host a different schema at a different endpoint. And god help any client that's not consistently up to date with the latest schema in all places. You want to query for new feature X only available in api v2, but your client is on api v1? Better go back and upgrade all your existing api v1 schema queries first. Or have a separate gql client for each api version, and remember to use the correct one in the correct place.

    Saying "just use better api design" isn't an answer to missing maps. Maybe I am dealing with third party data where I don't have control over the schema?

  • valenterry 2 days ago

    > > It doesn't support map/tables/dictionaries. This is actually huge. I get that there might be some pattern where you don't want to allow this but for the majority of situations working with json api's you'll end up with a {[key: string] : T} somewhere

    > unions

    Then you need to know the keys in advance

    > embedded types, and custom resolvers

    That is "kind of" cheating. I think OP meant a builtin type.

    > OR better api design

    Sometimes possible but not always.

    It's a valid criticism. Emulating another http endpoint in graphql should be super simpel in the best case, but sometimes it is not.

    Another example where that is true is union inputs - you can define and return a union of types, but you cannot accept the exact same union in a mutation. Very very unfortunate.

zelphirkalt 3 days ago

Do not forget, that GraphQL also cannot get you arbitrarily nested structure, if the client doesn't know the structure ahead of time. Its strength of defining of the structure you want returned, also becomes its weakness. If there is some tree structure you want to query, you will need to work around it. This has been discussed at length on github issues and there is unwillingness to change this. Who knows what kind of refactoring would be required for that to work.

However, I think GraphQL vs REST is a false dichotomy. One could probably maintain a GraphQL endpoint as well as a REST API, and use whatever is most appropriate for the use case of the client. People really should stop treating GraphQL as some kind of complete replacement for a REST API or "the new way of doing things" or acting like "the days of REST APIs are counted".

  • valenterry 2 days ago

    Yes, this is a very important point.

    One more very annoying shortcoming is that you can define a union of types and return them when queried, but you cannot write a mutation and ask the client to send the exact same union. You'll have to create different standalone mutations.

    In general the typesystem is quite lacking. But then again, it's better than pretty much everything else language-agnostic out there.

carapace 3 days ago

First, s/opinoin/opinion/

Second, there's a reason DBA (Database Administrator, something like that) is a formal, separate role.

If you don't have a DBA it's not because that's a good idea, it's because you (or your bosses) are too cheap to do things well. That's okay, a lot of times cheap is more important than correct.

You're still going to need schema.

Both NoSQL and GraphQL seem to throw the baby out with the bath water. It was all done before, and Relational Model won. Gotta know your history kids: https://en.wikipedia.org/wiki/Database#History

- - - -

Tidbit of lore: SQL is not the original language for relational model databases, Codd had a language he called Alpha: https://en.wikipedia.org/wiki/Alpha_(programming_language)

SQL is the JS of DBs!

spankalee 3 days ago

Among the many problems with GraphQL are

1) That it doesn't deal in graphs, but trees, and 2) It's not a query language, but an RPC language with result subsetting

I would love to see something similar to GraphQL that could return actual graphs. Like in the canonical Books/Authors example, a query over books that included the authors would return Books with _references_ into an Authors collection so that authors were not duplicated as children of the books.

I would also love to see real and standard query operations like where, limit, groupby, and ideally some sort of cursor. All that has to be added bespoke on top of GraphQL severely limiting the ability to write generic frontends and interfaces against GraphQL APIs.

Then there's the type-system problems like lack of Maps, the overly strict input/output separation, paltry scalar types with no standard for dates and times, etc...

  • nsenifty 2 days ago

    #1 is not a real problem on practice. If the concern is payload size, gzip solves it for the most part. If the concern is consistency (e.g. there's an update to author and it needs to propagate to all books from this author), most graphql clients + view frameworks already handle it by maintaining an id based cache and notifying all users of the said object when something changes.

  • nkozyra 3 days ago

    > 1) That it doesn't deal in graphs, but trees, and 2) It's not a query language, but an RPC language with result subsetting

    I'll resist pedantry on point one but I totally agree on point 2. Plus its syntax poorly reflects the data 'schema' it's defining.

throwawaymaths 2 days ago

I'm currently dealing with an openapi schema that declares a graphql query route. The mutations are still in rest (but it's only one endpoint -- You kind of use it like graphql). The graphql output is nonstandard so the reflection tools don't work.

The "cool" features of graphql (treating your data like a graph, so you that n+1 queries are not the consumer's issue to deal with) are not at all available, I sti have to manually do joins.

I am terrified that since graphql is all "you don't have to version your shit" there will be a breaking API change in the future that I (or worse, someone not me) will have to watch out for, so on that day our supply chain database will be horribly broken.

What the hell happened that we got APIs like this?

chpmrc 3 days ago

> It is actually a pain to use, depending on the backend you are using you'll have to manage two or more type systems if there are no code first generates in your language

This is a shortcoming of the language, not of GraphQL.

> It doesn't support map/tables/dictionaries. This is actually huge. I get that there might be

If you ever tried to cram a JSON like payload in a GraphQL field you'll know why this limitation is in place. It quickly starts getting abused by clients and you end up adding validation, which you might as well have codified in a properly structured type. For blobs you can just send encoded strings (JSON, base64, binary, you choose).

> No clear path for Api versioning you'll end up with MyQueryV1.01 MyQueryV1.02 MyQueryV1.03

The whole point of using something like GraphQL is that you don't need or even want versioning. You can still deprecate fields (and remove them according to your deprecation policy) but in general you can just keep adding fields/types without removing the old ones until you are sure consumers don't need them any more. So there's no breaking change and consumers can transition to the new fields whenever they want. Something else you start appreciating when you have multiple, heterogeneous consumers of your API.

Or you can just add the version to your schema URL, e.g. `/graphql/v1/` and then route your queries based on that, which kind of defeats the purpose.

> Invest your time in a simpler solution then running to GraphQL first

GraphQL is as simple to set up as anything else, assuming the language has good support for it. If it doesn't that's, again, a limitation of the language, not of GraphQL.

GraphQL solves a ton of problems related to typical JSON APIs' conventions, since JSON isn't inherently "schemable" unless you generate something like an OpenAPI spec which is, arguably, more complicated. There might be superior alternatives (I've never tried JSON schema) but I think all the pain points you described can be easily solved one way or another.

electrondood 2 days ago

We use GraphQL at my current company, but it's a service that sits between the backend and the frontend and just munges together several different API requests from one. It's... I really hate it. The way we're using it, it simply adds a layer of opacity that makes debugging a client-server issue a giant PITA.

I've worked at a few companies that used GraphQL poorly. I've yet to see it done in a way that makes me think it's the right tool for the job. And I understand the benefit of allowing the client to choose what they want to get back.

VoidWhisperer 3 days ago

As far as the versioning goes, the prevailing wisdom seems to be that it just isn't needed on graphql apis - on graphql.org they say the best practice is to avoid breaking changes. [1]

That said, versioning of a graphql api has been done at scale before. Shopify has done it, using versioning in the URL, specifically their admin data api, using month-year release dates as the versions [2]

[1]: https://graphql.org/learn/best-practices/

[2]: https://shopify.dev/api/usage/versioning

  • JohnHaugeland 3 days ago

    > As far as the versioning goes, the prevailing wisdom seems to be that it just isn't needed on graphql apis

    In reality, of course API versioning is needed.

    The "prevailing wisdom" is people who like the tool, don't like its limitations, and want to pretend it isn't a problem.

    .

    > That said, versioning of a graphql api has been done at scale before. Shopify has done it

    Perl people will happily point out that object systems exist for Perl.

    Having it not be a standard, uniform part of the core tool is a severe limitation. Shopify needed this rudimentary feature, and tried to give it away because others need it to, and the tool vendors aren't willing (or able) to deliver.

    • krschultz 3 days ago

      FB is pretty much on V1 of its GraphQL API with tens of thousands of engineers editing it for over a decade. Every single query is its own version, that's the point. If you want to change the semantics of a field, make a new field and leave the old one for the existing clients. What else would you have to version?

      • hu3 3 days ago

        We're not Facebook

    • PUSH_AX 3 days ago

      > In reality, of course API versioning is needed.

      I’d recommend not picking a technology that is versionless by design if you think you’re going to need it. Also I’d dispute that versioning is needed as a rule.

      • JohnHaugeland 2 days ago

        > I’d recommend not picking a technology that is versionless by design if you think you’re going to need it.

        I mean, I don't pick GraphQL, and this is just one small part of why.

        Every place that I've ever worked that's attempted to adopt GraphQL has rapidly given it up.

        .

        > Also I’d dispute that versioning is needed as a rule.

        The IEEE once measured peoples' expectations regarding how necessary versioning was, and got a response of something on the order of 40%. There was an uproar, and a whole bunch of people on both sides of the topic tried to call bullshit.

        Some middle manager somewhere sent in a letter that said approximately "how about you write a follow-up article where you bin the responses by years of experience?"

        The rest of the story writes itself.

Eric_WVGG 3 days ago

The syntax of GraphQL drives me utterly mad.

I feel like there’s two approaches that one could take to approach queries: a series of programming commands (the way most ORMs work), or an attempt at “plain language” (SQL and GraphQL).

Both approaches are fine, but if one wanted to take the latter approach… why not just use the syntax of SQL? It’s better in every conceivable way that GraphQL, equally legible but much more powerful.

GraphQL is idiot baby talk, I’m baffled by why we have to waste time dumbing down expressions for no clear payoff.

  • valenterry 2 days ago

    Yes and no.

    SQL also sucks, since you have to SELECT before defining FROM. Which means, code completion isn't there for SELECT. At least with graphql you get full code completion all the time. I agree though that it lacks in other areas. Choice between pest and colera.

ant1oz 3 days ago

I totally agree, the list of frontend pro is super cool, especially the subscribe real time API, but on the backend, it is a pure nightmare, either using very cutting edge third parties, the authorization is a super big pain in the butt to implement. Cool you got a graph, now you need to make sure only user a can edit row b, there is the shortest path, but the data storage is still centralised.

And I doubt there will ever be any PWA POSSIBLE with graphql, so no offline usage, no local storage , nothing cool toward the web6 decentralised stack.

noname120 3 days ago

Add the fact that the cache performance is unpredictable and inconsistent.

GraphQL queries select specific fields for “performance reasons” so each request is custom and you can't cache at the edge. This is ridiculous because SQL joins are costly but fetching a few extra textual fields is basically never a bottleneck.

So in order to save a few bytes or KBs (which nobody care about anyway), you ruin your caching abilities...

...Well unless you manually cache your GraphQL queries with more fields than needed but then what's the point of using GraphQL at all?

That's very often a terrible compromise.

criley2 3 days ago

GraphQL has advantages that make it great in certain situations but it can be very difficult to wrangle it at large scale and you basically need to hire Facebook GraphQL engineers once you get to a certain size.

If you are using Typescript on backend and frontend (react/reactnative ok, native ios/android app no) then checkout tRPC. https://trpc.io/ tRPC is basically: you just call your backend functions on your frontend, and TRPC handles the API that makes it work. It shares types and when you define a type for your backend, and call that function, you get the type on your frontend.

Incredible for small apps/teams, but has it's limitations (especially before the most recent version) and probably not the solution for a big honkin app.

I've been playing with create-t3-app and it's pretty nice, great way to launch a basic typescript/trpc/nextjs/prisma app. https://github.com/t3-oss/create-t3-app

I use GraphQL at work and it's fine, it's just a lot of code and codegen and work for a small team, we'd be faster on tRPC but tRPC didn't even exist when this codebase chose graphQL lol

bryanrasmussen 3 days ago

In the systems where I designed both front and backend and the API I did not need graphQl, but in many of the large companies I have come in to where things have been developed by many people over a significant length of time GraphQL really improved the frontend performance and time to release new functionality once it was introduced.

Perhaps it would have been the case if they just cleaned up and released a new Rest endpoint, but I'm not so sure.

mcv 2 days ago

I think a big one is: don't use GraphQL if you're only making the API for yourself or teams you're in close contact with.

My previous project involved complex data in a graph DB, and twice we considered if maybe we should use GraphQL. After looking into it, we decided to stick with REST, because it's easier, we're the only ones using our backend, and all our responses are highly customised for what we're going to use it for. GraphQL would be a lot of extra work for no real gain; maybe we would end up with somewhat less highly customised hard-coded Cypher queries, but then we'd have to figure out how to represent them in GraphQL and translate that to the queries we'd need, and that was not going to be trivial.

In my current project, other people made the opposite decision: they do use GraphQL for a fairly similar use case, and they regret it. It works, but it complicates things for fairly little gain. REST would have worked just as well.

E2EEd 3 days ago

I built an app with a REST API a long time ago, now a defunct startup. In an effort to save API calls, the front end devs requested that I add various other resources in new endpoints, often a subset of another endpoint's response fields. The API spec ended up being fairly unwieldy.

I've often thought that this would be a great use case for GQL. Seems like a good choice if your front end wants to specify exactly what data to get.

oznog 3 days ago

It's another postmodern web development fuck-up.

I saw it coming for miles and evaded it.

Your complexity is my competitive advantage. Please continue to be followers of any new shit.

anothernewdude 2 days ago

You just ignore the main selling point? It solves the latency of getting the data you need. The only alternative is to provide specific extra APIs.

If it's a pain to use, perhaps you're using the wrong language or framework.

You're right that many APIs have maps, those are bad APIs. The map should be happening in your API. The alternative was a poor workaround to stop latency in a REST api.

anotherhue 3 days ago

Comparing GQL to REST is like comparing a framework to a protocol. Of course it's easier to build up from REST, but if you're lucky enough that your project survives it won't be long before you're reimplementing the same GQL features you rubbished in a half-arsed way.

In an ideal world, we can grow into the tech pulling in features as needed, but REST (in its modern form) is all about day 1 productivity, not day 100.

  • yellow_lead 3 days ago

    > if you're lucky enough that your project survives it won't be long before you're reimplementing the same GQL features you rubbished in a half-arsed way.

    Unless you don't need those features to begin with? I also think with this mentality you'd end up with a lot of teams saying "lets do GQL in case we need it later" and it ends up being a ton of work for no benefit later.

TechZillennial a day ago

As a senior dev having worked with REST and GraphQL API's at scale, I'm afraid I must disagree.

I feel most people's negative opinions on GraphQL are mainly due to their own lack of familiarity and expertise on the subject. They simply don't want to RTFM.

When used properly and competently, the DX buffs far outweigh a traditional REST API.

rootext 3 days ago

> It doesn't support map/tables/dictionaries. This is actually huge.

It's actually easy to implement. Just define custom scalar type: scalar JSON type MyObject { myField: JSON }

https://www.apollographql.com/docs/apollo-server/schema/cust...

  • randytandy 3 days ago

    Hey thanks for taking the time to find the resource

    I have used this before this works to get past the errors but doesn't actually solve the issue GraphQL tries to solve. This just hides it so you have to deal with it months later.

    - The consumers don't know what the JSON looks like unless they test the query or get told what the query is explicitly. This means that the schema definitions don't capture the problem that the graphql try's to solve "describe your data that you want"

    - also some of the other languages that aren't Javascript don't have GraphqlJsonScalar

    I think that supporting dictionaries/maps/tables as apart of the Graphql language spec could of been possible as the key and value types are static. They are also iterable so it should be fairly straight forward for a consumer to deal with the data returned.

andrewingram 3 days ago

_Context: I do front-end and back-end, so I'm usually the one who ends up maintaining the GraphQL server_.

The vast majority of people who've used GraphQL haven't used it with something like Relay; and in my mind that means they haven't used GraphQL in a way that really shows off its strengths. This isn't to say that GraphQL doesn't have any benefits without Relay, but rather that the cost/benefit scale only really tip heavily towards benefits if you're using it to solve the problems it was intended to solve -- that of reliably getting a component's data dependencies into the component.

Every time I use GraphQL without Relay I find myself questioning whether it's adding anything except complexity, every time I use Relay (other than the initial architecture build, on-ramp is steep) it feels great. Relay's learning curve and poor documentation is really unfortunate, because the difference is quite pronounced.

infinitezest 3 days ago

Ive used GQL on several projects for work and its been _OK_ to work with but not really worth the hassle in our cases. It ended up costing us lots of time to onboard new devs and hasnt given is much in return aside from type safety between the front and back ends. Im sure there are good use cases for GQL but I have not personally run into them.

BLanen 3 days ago

Graphql gets hyped by people who have seriously no idea what the hard problems in apis are.

It quite literally solves many easy issues and pretends solve the hard ones, but does nothing to actually do this and just says that you "can".

I designed a typical JSON api that had customizable fields and filters and joins and authorization on orm level on classes(could easily be extended to do authorization on fields of the orm classes.) This was years before Graphql came along and pretends to solve these issues, while actually just leaving them up to the implementor of the resolvers. As if the idea itself of resolving per fields in so special.

And then you have people that think graphql = the semantic web(web3 before crypto shit stole the term). Inventing the same cyberpunk dreams from 40 years ago...

Nobody is even actually doing REST, just Rpcs over http with json. If they read the REST paper they'd know this is what they actually want but I fear it's a pipedream.

  • zoover2020 3 days ago

    I'm all for piggybacking off of Fielding's work, but HATEOS isn't practical and the industry reflects this.

    • BLanen 2 days ago

      It's not practical because HATEOAS and "Uniform interface" are unrealistic cyberpunk(in the 80s philosophical sense) pipedreams.

      But people who hype graphql seems to imagine graphql solves such things. Which it doesn't do at all.

NotTameAntelope 3 days ago

Meh, each of your complaints is solved by understanding GraphQL better.

If the main issue is you have to learn something complex, sure that’s probably a little fair, but it’s really easy to get GraphQL to do what you want once you’ve gotten over that initial learning curve.

Specifically, queries and mutations can literally do whatever you want them to.

jensneuse 3 days ago

The GraphQL specification doesn't mention HTTP. It's just a query language, like SQL, but with a different focus. I understand what people complain about in this discussion. It makes sense. Talking GraphQL between client and server can be a headache. That said, I'd like to propose a completely different use case. Have you thought about using GraphQL as a "meta-language" to compose APIs? A pure Server-Side solution to manage APIs as "dependencies", and turn them into a JSON-RPC API as you need them. I wrote about this here: https://docs.wundergraph.com/docs/architecture/manage-api-de...

I'm curious what people think about this use case of the Query language.

  • hn_throwaway_99 3 days ago

    > It's just a query language, like SQL, but with a different focus.

    No, no, no! I love GraphQL, and have been using it on projects for many years now, but the thing that is difficult for me to forgive the original designers of the spec that they put "QL" in the name, confusing so many developers into thinking it is a generic query language.

    GraphQL is simply a spec and contract for exposing an API. Its "competing technologies" are things like RESTful APIs and gRPC. It really has nothing to do with a generic "query language" like SQL.

    • mdaniel 3 days ago

      It is a query language in that one can select the fields one wishes to be returned, including conditional evaluation of interior clauses via e.g. https://spec.graphql.org/October2021/#sec--skip

      The field selection is certainly possible in REST via something like /foo?include=a,b,c but starts to get just downright silly with /foo?include=a,b.c[1].d,e[*].f which has now become its own DSL

hamandcheese 3 days ago

On the point of maps, I have had success solving this in two different ways.

Option 1: return a property list. In other words, a list of objects that have a key and a value. It’s easy write a getter function to search by key, or convert it to a map outright.

Option 2: make a Json custom “scalar”, send back whatever dynamic structure you want.

Abimelex 2 days ago

One of the most advantages of GQL is in my opinion that you have all you need in only one query. Every tried to query 3 levels or more via REST in frontend? A "user" with a "company" and the companies "employees" which might have some "attachments" or "cv's" linked ... all only ONE query in GQL, while with REST you would need to wait for the result of each query or to know the IDs in advance.

For all the security layers there are usually great frameworks doing the job.

comfuture 7 hours ago

definitly agree. If it's true, opening up the database port would be more worthwhile.

stutsmansoft 3 days ago

I also had a bad experience with graphQL, or perhaps more accurately the Apollo client for it.

I hated the namespaces on the code-generated classes and ended up manually wrapping them, obviating the benefit.

It was also super brittle, when the back end would change something it would break the clients.

tekknik 2 days ago

> It doesn't support map/tables/dictionaries. This is actually huge. I get that there might be

> some pattern where you don't want to allow this but for the majority of situations working with json api's you'll end up with a {[key: string] : T} somewhere

Please don’t use maps in API responses. Rarely do they map well and in all cases you can instead use a list of objects which is substantially easier to parse.

krschultz 3 days ago

- It shifts the complexity where it belongs - out of native apps deployed to user's phones and onto the backend that you control. It doesn't eliminate any complexity.

- There's really no need for API versioning in GraphQL. Just keep iterating on the fields.

randytandy 3 days ago

Hey all, didn't think this would be anything more than 1 or 2 comments.

I appreciate everyones passion and level of thought going into the replies. I will try read most of them.

Please note that if you reading this.

My intention of this post was to get a little rant off my chest and find out about potential solutions and gotchas about using GraphQl. It's unproductive attacking me or anyone else for character like "clearly not a senior developer" or "clearly never used API's before" because if anything this is about trying to find a solution and to save each other time.

Justsignedup 3 days ago

Personally I've used JSONApi

Pros:

- front-end implementation is near-trivial. I re-wrote half of my framework because I wasn't happy with it in a few days.

- can use some cookbooks for some good front-end patterns

- overall very easy to use, and very easy to extend front-end stuff

Cons:

- Poor back-end implementations. JSONApi Resources kinda sucks. Graphiti might be significantly better.

- No clear pattern for submission of data. You don't want your front-end to contain operational logic, dumb front-ends are the way to go (front-ends do what they are told, they don't make decisions).

- Not the "IT" thing, so not too much big corporate money backing it. :( This is actually kind of a big deal.

scottwick 3 days ago

A frontend application that I work on has each component making separate tiny GraphQL queries to render just what it needs. The result is often 5-10+ GraphQL requests to render a single page. Is this a common practice?

It seems like a lot of overhead to me since the backend has to perform some redundant queries (i.e. fetch and authorize the user, etc.) in order to serve each of those requests. I had thought one of the main selling points of GraphQL was that the frontend could make a single API request and have everything it needs to render the entire page. Any thoughts?

  • wes-k 3 days ago

    Use Apollo, it can stitch all those queries together into one deduped query. It’s awesome!

    • scottwick 2 days ago

      Could you point me to some documentation about this? Is this something that's built in to Apollo? Or just that Apollo enables building this sort of architecture more easily?

brillout 3 days ago

If you use Node.js, check out Telefunc[1] which enables you to seamlessly call Node.js functions from the frontend (in other words RPC). Including first-class TypeScript support.

Its guide "RPC vs GraphQL/REST"[2] explains you when to use GraphQL and when not.

[1]: https://telefunc.com/ [2]: https://telefunc.com/RPC-vs-GraphQL-REST

InvOfSmallC 3 days ago

I admit I never seen a use case that justify the complexity of usage. Let's say you have a native app and a web app. I don't see these 2 changing that much in terms of data so a an API middlelayer is just simpler.

At work we have a use case like: well we create the data layer that you can query the way you want and the field you want with many clients involved. So like an API where you can make composable queries.

To me that sounds like an API with query parameters, do we really need to use GraphQL?

Let's see!

  • Kamq 3 days ago

    > I admit I never seen a use case that justify the complexity of usage. Let's say you have a native app and a web app. I don't see these 2 changing that much in terms of data so a an API middlelayer is just simpler.

    It has some benefits when you have multiple different products that need different "pieces" of the data, rather than 2 different clients for the same product.

    I never quite understood how much hype it got, but it provides some nice benefits in an internal corporate environment, especially when data within said environment has an "owner" and accessing it from a new place requires an entire process.

    • InvOfSmallC 2 days ago

      Yeah the project where we are going to use it consumers will do different products with the same data.

      So I’m curious to see how this will we actually implemented.

      (We also have Kafka topics where you can consume all the sources in your storage but that gives other problems so I’m not completely negative on giving a single point where you can aggregate data)

  • nrb 3 days ago

    > To me that sounds like an API with query parameters, do we really need to use GraphQL?

    Do you care about the API being discoverable and the schema being well described? Being able to see the relationships between the data? The type-safety that comes from the tooling? The ability to expose the field once on an entity that allows consumers to use it in any variety of queries?

    • InvOfSmallC 2 days ago

      I may have not done all my home works on the matter but how’s that different from exposing an OpenAPI that your client can consume and generate all needed classes etc… on top of that?

FpUser 3 days ago

All my backend servers expose JSON based RPC api. It does exactly what was intended. No more no less. Works like a charm. I can hardly imagine why would I want to invest in developing / exposing GraphQL layer. Facebook might have their valid reasons but businesses/clients I deal with are not FB scale and do not really give a flying fuck about what FB does. They just need to solve their own particular problems with good ROI.

jsdwarf 3 days ago

GraphQL Performance is abysmal, because query language is completely detached from the way data is stored and encourages you to select as much as possible.

b33j0r 2 days ago

I loved the idea, then I found out that _doing_ anything devolved into completely custom RPC implementations.

I’m not always RESTful, but in GraphQL the state transfer part is left as an exercise for the reader.

I love natural data models. I also think RPC makes sense when there are clear verbs in a system.

Poor GraphQL. It’s like a Greatish novel where the first half is compelling and intricate, and the last half was rushed by the publisher.

nazka 3 days ago

I feel 2 critical points are missing in the bad things: some control and security on the backend side, and more importantly scaling. Did these things got fixed? What is the cost on the cloud versus the same backend with an API (I saw a horrible story about that). Can I cache queries efficiently? Is it efficient and fast with high throughput of RPS? Or tell GraphQL to use Redis for some data? Etc...

jasonhansel 3 days ago

IMHO the biggest issue with GraphQL is that it's often used in a way that effectively breaks encapsulation. When you use GraphQL, it's hard to limit the API surface of a service to avoid exposing implementation details. This means it's difficult to modify the internals of a service without breaking its clients, and it can make things like testing and versioning more of a challenge.

alexnewman 3 days ago

I usually agree with stuff like this, but this one is wrong. It is true that graphql is overused, but frankly stuff like thegraph.com make graphql Freaking amazing! it's totally eliminated our need for anything like a backend to make stuff like https://dashboard.humanprotocol.org/

gsvclass 2 days ago

It depends on how you use it. With GraphJin you use GraphQL to define your API and GraphJin auto compiles it into SQL and instantly gives you a REST and a GraphQL API endpoint to use it with.

https://github.com/dosco/graphjin

willjp 3 days ago

I think graphql is fantastic, and solves tricky design decisions (versioning, precise rest queries). However, I don't believe all graphql client libraries are created equally, and I strongly prefer those that are simpler, and closer to graphql's own syntax (ex. ariadne). This is an opinion though, my preference is generally explicit > implicit.

  • pheres 2 days ago

    or server libraries for tha matter.

    Everyone's experience differs quite a bit depending on the used client library (plain, apollo or relay) or the server library specific for your server languages.

sebnukem2 3 days ago

I'm happy to read this. I had to use GraphQL once in an old job and I hated, hated the freaking thing with a passion, but there was so much hype about it I concluded the problem with it was caused by myself, a getting older and more close minded self. I see now that GraphQL may not be that wonderful, after all.

gorjusborg 3 days ago

GraphQL isn’t a panacea. It has strengths and weaknesses.

This is true of any technology, so if you think the tech you are using doesn’t require a trade-off of some sort, you are likely missing something.

I’ve yet to select GraphQL over straight RESTful APIs, but I also don’t work in an ecosystem where disparate client needs are important.

chrisweekly 3 days ago

IME GraphQL is kinda great on the consuming side, but the complexity and maintenance overhead of query resolvers can outweigh the benefits. I agree that it makes sense to look elsewhere first. For example, react-query can solve many of the problems GraphQL aims to solve (eg overfetching), without the downsides.

  • wizofaus 3 days ago

    Can you expand on that? If your existing RESTish/JSON Api doesn't support the level of fine tuning of what data you want back, how can react-query prevent overfetching? I ask because I'm currently involved in converting some code over to react-query, despite the fact there's a longer term plan to move to GraphQL which I'm concerned will obviate the need for the current rewrite.

yetanotherloser 3 days ago

Always sad at wasted effort but something here feels odd to me. Use graph technologies if you genuinely have a graph problem; use graph technologies if you have an "almost tree but..." problem; don't use graph technologies if you have a strict tree problem or a table problem. This all feels like a meta- version of "social pressure pushed me to use the wrong conceptual model". All the cool kids were doing it...

That said, graphs are dangerous because they are so flexible; you can draw a tree or a table in one and it all seems fine but you're paying all the time in conceptual load and friction.

Microcosm: graph vs table db. In the middle: social pressure dominating data model choices. Macrocosm (relatively speaking): The swing of the pendulum between bodgy vernacular attempts to describe the world (dev don't need some control freak's schema) and esoteric priesthood attempts to describe the world (all knowledge graph structural changes must be initiated by our ontologist...).

maximilianburke 3 days ago

One of the things I dislike about GraphQL is that though the standard doesn't really specify a format all the implementations are closely tied to JSON.

Between that and the (at the time, anyways) abysmal serialization performance of Juniper we ended up abandoning GraphQL.

enahs-sf 3 days ago

My main gripe with it is it’s an added level of indirection that makes debugging just a little more difficult.

Back in the good old days, you could open up the network tab, see the request made by the client and copy as curl to debug it.

Now with SSR and graphql, such a workflow is out the window.

phendrenad2 3 days ago

I also refuse to use GraphQL (after seeing it fail utterly and spectacularly in a high-profile project that chose GraphQL because it was the "new shiny"). But I'm sure it has some niche that it works for. After all, people are still using it in 2022.

dqpb 3 days ago

I have only played with GraphQL a little, but from what I could tell, the client can’t define the structure of the response, they can only choose to have some fields missing. Am I wrong, or is that basically all it does?

ramesh31 3 days ago

It suffers the same peoblem as WSDL, (or “proper” REST for that matter), which is inflexibility and boilerplate. It provides a mechanics garage worth of tooling when you probably just need a swiss army knife.

Aeolun 2 days ago

> No clear path for Api versioning you'll end up with MyQueryV1.01 MyQueryV1.02 MyQueryV1.03

Think very hard about your API. And absolutely do not ever introduce any query called V1 or V2.

endisneigh 3 days ago

What exactly is the simpler solution that doesn’t result in your same cons mentioned?

  • thomassharoon 3 days ago

    There are patterns that can get you the same benefits without having to use GraphQL.

    Even on a REST API, you can achieve the same pros

    > - It makes working with describing the data you want easy > - It can save you bandwidth. Get what you ask for and no more

    You can describe the fields you need (and I assume that is what reduces the bandwidth)

    GET /users?fields=name,addresses.street,addresses.zip

    > - It makes documentation for data consumers easy

    I don't think so in practice. You can see Shopify's GraphQL documentation [1]. If anything it is more complex than their REST API docs

    > - It can make subscription easier for you to use

    Not too different from using something like SSE or even websockets and every decent web framework seems to have a decent implementation

    > - Can let you federate API calls

    So many ways to achieve this at the application layer (which is what GraphQL federation does with a Router). In the python world this could be separate WSGI apps or racks in ruby? And makes no difference if done at the load balancer level.

    [1] https://shopify.dev/api/admin-graphql/2022-07/enums/localiza...

    • endisneigh 3 days ago

      There a lot of ways to do the same thing as GraphQL. The point is if it’s as easy.

  • hestefisk 3 days ago

    SQL statements wrapped in function calls.

  • JohnHaugeland 3 days ago

    Making a regular api

    • endisneigh 3 days ago

      A regular api poorly implemented will have all the same cons and none of the pros.

      • geysersam 3 days ago

        Just make a perfect api without any drawbacks.

        • endisneigh 3 days ago

          GraphQl has a set of trade-offs. REST also has trade-offs. Bespoke RPC calls have trade offs. It's as if the entire discipline is an exercise in selecting trade offs or something.

          • anotherhue 3 days ago

            Well put. Problem is we can get emotionally invested and tie our identities to these systems in a way that we couldn't if we were comparing the trade-offs between 18/10 and 18/12 inox steel.

      • JohnHaugeland 3 days ago

        > A regular api poorly implemented will have all the same cons and none of the pros.

        Okay, so don't make a poorly implemented one?

        Also, no, it kind of won't. Let's look at what they are again

        .

        "It is actually a pain to use"

        Not an API characteristic

        .

        "you'll have to manage two or more type systems if there are no code first generates in your language"

        Not an API characteristic

        .

        "It doesn't support map/tables/dictionaries."

        Not an API characteristic

        .

        "No clear path for Api versioning"

        Not an API characteristic

        .

        Looks like it's actually zero for four

        • gabereiser 3 days ago

          In order to build a properly implemented one, one must first learn to build one. I find most people jump onto graphql because they see the volume of work to create crud endpoints for all of their models and decided to punt.

          • legalcorrection 3 days ago

            It’s a false promise. You’re just moving the complexity elsewhere, into wiring this ridiculous graphql infrastructure together and making it actually do what you want in all but the simplest/tutorial-like scenarios.

            • intelVISA 3 days ago

              Seriously. I sometimes think I'm visiting a satirical alter realm when I see these obtuse systems that end up requiring more cognitive energy to glue together than the regular version in <lang of your choice here> being praised rather than derided.

              • lelanthran 3 days ago

                > I sometimes think I'm visiting a satirical alter realm when I see these obtuse systems that end up requiring more cognitive energy to glue together than the regular version in <lang of your choice here> being praised rather than derided.

                You're lucky, you're only visiting. I'm working in that alternate reality :-)

pharmakom 3 days ago

GraphQL let’s you write optimisations once that apply across all you queries which is a huge advantage.

I think we can do better than GraphQL but until that solution arrives and achieves wide adoption I will keep using it

mattbillenstein 3 days ago

IMHO, it's a better contract with frontend apps than REST, but you have to be mindful of the backend implementation and the shape of the GQL schema more or less matching your DB schema.

ramesh31 3 days ago

I woyld really love to be able to consume GraphQL API’s all the time, but I would never ever want to have to write or maintain one. That pretty much sums up the problem.

svnpenn 3 days ago

> It can save you bandwidth. Get what you ask for and no more

I don't, and never have believed this argument. I would bet that JSON with Gzip or Zstd is just as small, or close enough that it doesn't matter.

  • speedgoose 3 days ago

    A graphql query is usually sent inside a JSON document and a graphql response is usually a JSON document sent over HTTP with compression. You do have to upload the query but you can select only the data you need, and you can also do that in a single query compared to a classic almost REST API. That’s the part that saves bandwidth, sometimes.

  • itsdrewmiller 3 days ago

    If you have any data sets with an open text field that you don't care about, or where you really only need to get the ID from a wide table, it will definitely save a ton of bandwidth. How often that really matters on the other hand...

    • horsawlarway 3 days ago

      And in this case usually you can easily opt to exclude the troublesome field with a param, or an endpoint that returns a minimum version of the entity.

  • locutous 3 days ago

    Nothing prevents you from compressing the smaller response of what you asked for.

4dregress 3 days ago

Being a good engineer (in any domain) means you have the experience to can pick the correct tools for the job and then explain why you have chosen those tools.

It all depends on what the end goal is.

Lapsa 3 days ago

when I talked about drawbacks of graphql like 3 years ago - I got ridiculed. there surely are some nice perks but overall - I find the maintenance of that tricky abstraction layer way too exhaustive. then there's that (weird) architecture in which all the data goes through single focal graphql endpoint. I mean - there's already painful client/server division in web world but now the server knows near nothing about the client intent.

pharmakom 3 days ago

I like GraphQL because it allows me to expose the data once and then let front end devs run with it. It’s a bit of work upfront but it’s less work over time.

pikdum 3 days ago

PostGraphile works really well for us. We had a lot of issues when we were previously trying to wire things together ourselves, though.

NonNefarious 3 days ago

I was psyched to hear about GraphQL, but when I looked at it and found no apparent way to do joins... I wondered what the big deal is.

  • vlod 3 days ago

    I think the general idea is that it's a graph rather than relations.

    You "join" by using the parent ID (e.g. employerID of parent container to get employees). This can (and often) introduces an n+1 problem unless you watch for it and use dataloaders.

    Not saying this is great or anything. :)

    • NonNefarious 3 days ago

      Thanks. The issue is what if I want to pull all the employees from the table of all customers, to determine how many employees have made purchases under our employee-discount plan?

      I just made that up as something that would likely require a join without really thinking it through too much...

spullara 3 days ago

GraphQL can also be a performance nightmare if you aren't rewriting every GraphQL query into a single SQL query.

  • jahewson 3 days ago

    Same applies to REST APIs if you don’t offer batch endpoints. Most of those n+1 query examples I see thrown at GraphQL would be n+1 GETs in REST.

    • spullara 3 days ago

      For sure. Don't do that.

ChicagoDave 2 days ago

For me, the biggest con is that it makes _business modeling_ opaque.

I want all of my code to be readable by non-programmers.

vikR0001 3 days ago

When you say it doesn't support tables, can you provide more info? GraphQL can return lists of course.

bdlowery 3 days ago

Yeah… but Shopify forces me to use it when accessing their storefront api.

didip 3 days ago

graphql sucks ass for backend and infra people, the people who need to scale it.

It also doesn’t speak normal REST dialect so you are missing out on basic things like status 200.

wzy 3 days ago

GraphQL: A whole lot of work to do REST differently

  • x86x87 3 days ago

    A whole lot of work to do REST poorly.

    • speedgoose 3 days ago

      Which is a good thing, because REST is not that great outside basic CRUD apps with tiny models.

raydiatian 3 days ago

Check out EdgeDB, and EdgeQL

Kalanos 3 days ago

it' a hack substitute for a graphdb

OOPMan 2 days ago

GraphQL was something I disliked on sight.

legalcorrection 3 days ago

Ignore all the noise and just use an RPC model between your backend and frontend. All these stupid trends and overengineered abstractions will come and go, but people will still be using plain RPC in 5, 10, 100, and 1000 years.

  • mark_and_sweep 3 days ago

    But before you use RPC, try rendering your markup on the server. That, too, reduces a lot of complexity.

    • samarthr1 3 days ago

      At cost of reducing cache ability though no?

      It is cheaper for me to put my react app in front of a cdn, split out my app into an api and front end than for me to have my site be entirely uncacheable.

      I can also cache certain endpoints behind the cdn that are mostly invariant for users. And, the network egress of json is much lesser than the egress of markup.

      • jddil 3 days ago

        What? Server rendered content is infinitely more cacheable, maybe I'm not understanding what you're saying.

        In the boring old days we just did it all on the server and used the semantics of HTTP to handle caching ... it worked great.

      • mark_and_sweep 2 days ago

        If you are truly concerned about network costs, I'd recommend rendering an XML model on the server and using a cached extensible stylesheet (XSLT) to render your HTML on the fly, on the client.

    • runald 3 days ago

      and let all the non-browser clients parse html?

  • jddil 3 days ago

    The longer I do this the more I realize the part of engineering most of us enjoy is solving a problem in a novel way. Which means if left to their own devices engineers will recreate the entire tech stack every few years instead of using the shit we've already built 20 years ago cause it's too boring.

    • x86x87 3 days ago

      Resume driven development. It's the same shit: reinvent stuff. Use "cutting edge" tech. Get credit, move on. Who has time to just solve the problem and build something that just works?

chrischen 3 days ago

Facebook intended it to be used with Relay... so a lot of problems can be avoided by using Relay.

jddil 3 days ago

I'm glad the tide seems to be turning against GraphQL.

Your company is not Facebook, you don't have an impossibly large graph dataset that needs querying

I've used it 3 times, each time it was a nightmare. REST with some additional params to query extra data is so much easier and safer ... that's just not very cool I guess.