11 ms·
GraphQL kinda sucks
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
- stutsmansoft 4y agoI 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.
- gorjusborg 4y agoGraphQL 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.
- mattbillenstein 4y agoIMHO, 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.
- didip 4y agographql 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.
- ramesh31 4y agoIt 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.
- ramesh31 4y agoI 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.
- comfuture 4y agodefinitly agree. If it's true, opening up the database port would be more worthwhile.
- deleted 4y ago[deleted]
- endisneigh 4y agoWhat exactly is the simpler solution that doesn’t result in your same cons mentioned?
- JohnHaugeland 4y agoMaking a regular api
- endisneigh 4y agoA regular api poorly implemented will have all the same cons and none of the pros.
- geysersam 4y agoJust make a perfect api without any drawbacks.
- deleted 4y ago[deleted]
- endisneigh 4y agoGraphQl 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 4y agoWell 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.
- deleted 4y ago[deleted]
- JohnHaugeland 4y ago
- VoidWhisperer 4y agoAs 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/ https://graphql.org/learn/best-practices/ [2]: https://shopify.dev/api/usage/versioning https://shopify.dev/api/usage/versioning
- JohnHaugeland 4y 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.
- PUSH_AX 4y 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 4y 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.
- legalcorrection 4y agoIgnore 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 4y agoBut before you use RPC, try rendering your markup on the server. That, too, reduces a lot of complexity.
- deleted 4y ago[deleted]
- samarthr1 4y agoAt 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 4y agoWhat? 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 4y agoIf 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 4y agoand let all the non-browser clients parse html?
- gabereiser 4y agoI 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.
- PUSH_AX 4y agoAnd 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.
- locutous 4y agoI 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.
- vlod 4y agoI think Apollo Federation is for that: https://www.apollographql.com/docs/federation/ https://www.apollographql.com/docs/federation/ Worth watching some youtube tutorial videos. Here's one I watched recently (~26mins): https://www.youtube.com/watch?v=v_1bn2sHdk4 https://www.youtube.com/watch?v=v_1bn2sHdk4
- gabereiser 4y agoNot everything is a graphql api
- soccersofia15 4y agoSame! We’ve been using WunderGraph to help with schema stitching and integrating other data sources
- svnpenn 4y 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.
- locutous 4y agoNothing prevents you from compressing the smaller response of what you asked for.
- itsdrewmiller 4y agoIf 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 4y agoAnd 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.
- speedgoose 4y agoA 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.
- chrischen 4y agoFacebook intended it to be used with Relay... so a lot of problems can be avoided by using Relay.
- OmarIsmail 4y agoYes, 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 4y agoDoes 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.
- mabbo 4y agoWhether 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.
- grumple 4y agoCurious 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).
- mabbo 4y agoHonestly it's mostly just lack of familiarity, which is getting better every day.
- syastrov 4y agoe.g. postgraphile
- toolz 4y agobecause 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 4y agoWhat 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.
- jwr 4y 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.
- spion 4y agoAgreed. 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-builder/blob/main/examples/test-zeus.ts https://github.com/typed-graphql-builder/typed-graphql-build... No docs yet, that's WIP
- eurasiantiger 4y agoIt looks like a lot more boilerplate than normal GraphQL queries.
- spion 4y agoNot 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 4y agoHmm, 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.
- deleted 4y ago
- geuis 4y agoIt'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.
- eknkc 4y agoSo 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 4y agoTheir service scope is waaaay too broad, no reason to be responsible for quasi banking services, traffic fine payment, and utility payment processing.
- CRConrad 4y agoServices like those are part of the scope of quite a lot of national post institutions, and actually for quite valid reasons.
- soccersofia15 4y agoBased 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 4y agodoesnt matter how beautiful the engineering culture/talented the pool if it works on ads/surveillance/facebook.
- 4y ago
- carapace 4y agoFirst, 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 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) https://en.wikipedia.org/wiki/Alpha_(programming_language) SQL is the JS of DBs!
- thdxr 4y agoBe 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.
- meesterdude 4y ago> Given enough experience / skill you can make any technology fairly enjoyable Have you never used MongoDB?
- thdxr 4y agohttps://twitter.com/thdxr/status/1394903426023272452?t=BjMUo7AoXv9OhYJB06wqBA&s=19 https://twitter.com/thdxr/status/1394903426023272452?t=BjMUo...
- philliphaydon 4y 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.
- grumple 4y 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.
- philliphaydon 4y 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.
- vsareto 4y ago
- datalopers 4y agoGraphQL's primary feature is enabling data exfiltration for bad actors
- x86x87 4y agoThis 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 4y agoIf 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 4y agoThat'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?
- chrisweekly 4y agoIME 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 4y agoCan 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.
- jongjong 4y agoSome 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.
- endisneigh 4y 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/ 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 4y agoIf 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.
- noname120 4y agoAdd 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.
- jddil 4y agoI'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.
- lofatdairy 4y agoFrom 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 4y agoSome 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.
- hn_user145 4y agoIn 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 4y 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
- anotherhue 4y agoComparing 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 4y 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.
- mLuby 4y agoHaving 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 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.
- danabrams 4y ago100% 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 4y agoNobody 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.
- ako 4y agoWhat 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?
- NonNefarious 4y agoI 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 4y agoI 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 4y agoThanks. 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...
- kehrin 4y 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 4y agoI think they were complaining that you couldn’t get back a query with unknown keys like a “select * from my_table” GQL equivalent
- drcode 4y agoThat 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.
- kehrin 4y agoBut 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 4y agoIt'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.
- the_mitsuhiko 4y ago
- cube2222 4y agoHaving 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.
- nip 4y agoN+1 queries performance in GraphQL is solved problem with dataloaders [1] [1]: https://sixfold.medium.com/reducing-database-queries-to-a-minimum-with-dataloaders-cc98c25e54ce https://sixfold.medium.com/reducing-database-queries-to-a-mi...
- vikR0001 4y agoWhen you say it doesn't support tables, can you provide more info? GraphQL can return lists of course.
- cersa8 4y agoI 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.
- vlod 4y 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 4y agoThe 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.
- wzy 4y agoGraphQL: A whole lot of work to do REST differently
- x86x87 4y agoA whole lot of work to do REST poorly.
- speedgoose 4y agoWhich is a good thing, because REST is not that great outside basic CRUD apps with tiny models.
- BLanen 4y agoGraphql 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 4y agoI'm all for piggybacking off of Fielding's work, but HATEOS isn't practical and the industry reflects this.
- BLanen 4y agoIt'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.
- krschultz 4y 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.
- phendrenad2 4y agoI 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.
- pikdum 4y agoPostGraphile works really well for us. We had a lot of issues when we were previously trying to wire things together ourselves, though.
- willjp 4y agoI 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 4y agoor 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.
- Guid_NewGuid 4y agoHmm, 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 4y agoYou 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 4y 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.
- 4y ago
- jasonhansel 4y agoIMHO 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.
- enahs-sf 4y agoMy 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.
- 4dregress 4y agoBeing 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.
- sebnukem2 4y agoI'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.
- rootext 4y 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/custom-scalars/ https://www.apollographql.com/docs/apollo-server/schema/cust...
- randytandy 4y agoHey 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.
- jensneuse 4y agoThe 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-dependencies-explicitly 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 4y 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 4y agoIt 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 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
- cletus 4y agoMy 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.
- hamandcheese 4y agoMy 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.
- alexnewman 4y agoI 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/ https://dashboard.humanprotocol.org/
- ant1oz 4y agoI 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.
- lfauve 4y agoThere is: https://rxdb.info/replication-graphql.html https://rxdb.info/replication-graphql.html
- pharmakom 4y agoGraphQL 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
- hamandcheese 4y agoOn 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.
- pharmakom 4y agoI 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.
- nazka 4y agoI 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...
- maximilianburke 4y agoOne 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.
- dmitryminkovsky 4y agoSome 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 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 4y 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.
- deleted 4y ago[deleted]
- Lapsa 4y agowhen 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.
- Justsignedup 4y agoPersonally 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.
- InvOfSmallC 4y agoI 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 4y 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 4y agoYeah 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 4y 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?
- infinitezest 4y agoIve 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.
- E2EEd 4y agoI 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.
- NotTameAntelope 4y agoMeh, 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.
- alerighi 4y agoTo 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.
- aleclm 4y agoWe 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 4y 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).
- kortex 4y agoI 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 4y agoI 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.
- andrewingram 4y 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.
- rglover 4y agoHaving 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 https://github.com/cheatcode/joystick [2] https://github.com/cheatcode/joystick#api-1 https://github.com/cheatcode/joystick#api-1
- charbull 4y agoWhat about sparql?
- stickfigure 4y agoThe 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.
- SnowHill9902 4y ago> It's easy to construct a query which puts unreasonable load on your system. Can you give an example?
- pdpi 4y agoDetails will depend on your schema, but the moral equivalent of “SELECT * FROM master_table” is a good start.
- withinboredom 4y agoHave 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 4y agoHasura 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.
- scottwick 4y agoGraphQL 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.
- oznog 4y agoIt'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.
- spankalee 4y agoAmong 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...
- nkozyra 4y 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.
- nsenifty 4y 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.
- humbleMouse 4y ago
- scottwick 4y agoA 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?
- FpUser 4y agoAll 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.
- sonthonax 4y agoGraphQL 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.
- deleted 4y ago[deleted]
- criley2 4y agoGraphQL 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/ 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 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
- dqpb 4y agoI 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?
- bdlowery 4y agoYeah… but Shopify forces me to use it when accessing their storefront api.
- yetanotherloser 4y agoAlways 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...).
- 0x20cowboy 4y agoIf 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.
- spullara 4y agoGraphQL can also be a performance nightmare if you aren't rewriting every GraphQL query into a single SQL query.
- raydiatian 4y agoCheck out EdgeDB, and EdgeQL
- bryanrasmussen 4y agoIn 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.
- replygirl 4y 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
- valenterry 4y 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.
- initplus 4y agoIn 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?
- Eric_WVGG 4y agoThe 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 4y agoYes 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.
- zelphirkalt 4y agoDo 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 4y agoYes, 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.
- brillout 4y agoIf 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/ https://telefunc.com/ [2]: https://telefunc.com/RPC-vs-GraphQL-REST https://telefunc.com/RPC-vs-GraphQL-REST
- jsdwarf 4y agoGraphQL Performance is abysmal, because query language is completely detached from the way data is stored and encourages you to select as much as possible.
- jeroenhd 4y agoMy 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 4y agoI 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 4y agoStrawberry (a GraphQL lib for Python) actually supports using generics to define types, it’s often used for supporting repetitive structures like pagination.
- chpmrc 4y 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.
- randytandy 4y agoHey 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.
- Kalanos 4y agoit' a hack substitute for a graphdb
- throwawaymaths 4y agoI'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?
- b33j0r 4y agoI 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.
- anothernewdude 4y agoYou 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.
- gsvclass 4y agoIt 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 https://github.com/dosco/graphjin
- electrondood 4y agoWe 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.
- OJFord 4y agoYou 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.
- initplus 4y agoOur monitoring says all the requests are 200 OK, why is the client down?
- ojkelly 4y agoYour 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 4y agoLike 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 4y 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?
- ChicagoDave 4y agoFor me, the biggest con is that it makes _business modeling_ opaque. I want all of my code to be readable by non-programmers.
- OOPMan 4y agoGraphQL was something I disliked on sight.
- Aeolun 4y 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.
- bigmattystyles 4y agoI'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.
- blacklight 4y agoWe'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.
- OrangeMusic 4y agoYou may find this article interesting: https://xuorig.medium.com/no-graphql-persisted-queries-are-not-re-inventing-a-rest-api-dcca7e876f7d https://xuorig.medium.com/no-graphql-persisted-queries-are-n...
- mcv 4y agoI 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.
- Abimelex 4y agoOne 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.
- SZJX 4y agoMy 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.
- tekknik 4y 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.
- TechZillennial 4y agoAs 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.
- mrbonner 4y agoI’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?
- gloosx 4y agoGraphQL 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
- soggybutter 4y agoI've only used GraphQL at my last two gigs, and didn't work with it full time. So there's a massive grain of salt. I think GraphQL is _mostly_ fine as a technology, but it seems incredibly easy to misuse and abuse. Particularly the fact that you can write arbitrary resolvers for specific fields and include any amount of business logic you like. It blurs the line between GQL being an interface to your API and actually being the API, and invariably it seems that too much logic gets put into resolvers because it's so easy. As far as I can tell, one of the best ways to use GraphQL is as a sort of RPC framework. At which point, my question becomes why not just use an actual RPC framework? Personally I find the field filtering and reduced network I/O to be overblown. Anecdotally, most of the GQL queries I've seen request HUGE amounts of data up front to reduce the number of overall requests that need to be made. Obviously not saying that's everyone's usage, but in my experience GQL has never really been much of a value add.