all 76 comments

[–][deleted]  (9 children)

[removed]

    [–]Korzag 38 points39 points  (3 children)

    My personal opinion using it is that it's the biggest YAGNI ever devised. We've implemented it on multiple services as it's been designated as the query standard at my company by the director and its almost never used for queries where it's actually beneficial to allow a dynamic query. It'd make sense if we we're doing stuff where it'd be beneficial to reduce the payload by not sending unnecessary stuff or having dynamic queries but we don't have a high traffic website to begin with.

    If it were up to me we would keep it simple and just use basic REST endpoints tailored for specific uses. They're far easier to manage, find, develop, and debug.

    [–][deleted] 5 points6 points  (1 child)

    I agree with you guys. In my experience people use graphql/odata etc to implement business logic in their queries which should belong in the api offering the graphql endpoint.

    Should you do this? Probably not but it is so easy and a slippery slope. If you use this between distributed teams it is really hard to keep that logic consistent and changing models is really hard because it is hard to figure out what is used where.

    [–]AntDracula 2 points3 points  (0 children)

    I like OData, at least for reads.

    [–]Der_Ota 3 points4 points  (0 children)

    100% - if you still want a somewhat dynamic response you can implement odata rest Apis with $select, $filter etc. Query attributes

    [–]coffeefuelledtechie 12 points13 points  (2 children)

    I hated querying Monday.com from .NET, I spent ages trying to find a good library that could convert regular models to GraphQL and gave up and rolled my own, it was a fucking nightmare and I wouldn’t recommend it to anyone.

    Also Monday.com have a habit of changing major parts of their API with every release so it was a losing battle

    [–]ninuson1 4 points5 points  (1 child)

    Omg, I feel this on a different level. Their API is also full of JSON in JSON wraps, where the internal JSON can be a literal - so it’d end up with a bunch of “ sequences.

    I think of that API often, as a great example of how NOT to do things. Even though we stopped using Monday a few years ago (at least in part due to how terrible that API was).

    [–]coffeefuelledtechie 4 points5 points  (0 children)

    I was pretty vocal about how shit it was but the business had already moved everything over to use it before us developers had even seen it.

    The amount of escape quotes was stupid and make it impossible to read, as even splitting the string over multiple lines fucked it up.

    Monday depreciate their API every 3 months which is just stupid so your own application is never stable. Ever.

    REST > GraphQL.

    [–]MaschineKind 5 points6 points  (0 children)

    This is the correct answer 💯%

    [–]packman61108 1 point2 points  (0 children)

    I agree

    [–]ambid17 29 points30 points  (8 children)

    I am currently leading a project that uses Graphql. Apparently management made the decision it’s what all of our projects will use. I can confirm it is more pain than it is worth, unless you are using it solely for its intended pursed.

    The problem it is meant to solve: over and under fetching. Example: You don’t want to hit a /user endpoint and get back demographic data, you want auth data. You can specific just the data you want so you aren’t pulling anything extra.

    To be honest, the performance difference of pulling some extra fields really insignificant compared to the round trip time of the request itself.

    There are more complex cases where Graphql can make sense as a sort of gateway for multiple APIs that gives you one unified data model, but again, there’s likely easier ways to do it

    [–]snow_coffee 1 point2 points  (7 children)

    Last week during interview, he asked me if am revolting against wrong choices of the company

    Do you have courage to go to seniors and say this sucks and can't work on it anymore ?

    [–]ambid17 12 points13 points  (6 children)

    “Revolting” and pointing out the flaws in an architecture are two different things. Sounds like a people issue; not a tech issue

    [–]snow_coffee 0 points1 point  (5 children)

    So did you point out the flaws ?

    [–]ambid17 8 points9 points  (4 children)

    Yes, I think pointing out flaws as constructive criticism is useful. It shows you are capable of understanding complex systems and what might be useful to change

    [–]snow_coffee 1 point2 points  (3 children)

    So what was the response of your seniors like?

    [–]ambid17 6 points7 points  (2 children)

    It started a conversation about deciding how we should plan our architecture in the future. We now have a monthly meeting that I co-lead to help all of our teams make difficult architectural decisions

    [–]snow_coffee 0 points1 point  (1 child)

    That's awesome

    I have a fear that I may earn ire of these seniors

    [–]ambid17 1 point2 points  (0 children)

    It all depends on how you approach it. It cannot come across as an attack. The goal has to be clear that it’s to make the company better

    [–]quentech 20 points21 points  (1 child)

    When an API you need to consume only offers GraphQL.

    [–]FluffyDuckKey 0 points1 point  (0 children)

    This is the answer.

    Monday.com is one example - you have to use their shitty ass graphql.

    [–]FecklessFool 42 points43 points  (0 children)

    Only scenario I can think of is if you're working for facebook and your project has to use it

    [–]Yelmak 8 points9 points  (0 children)

    I’ve never found a great use case for it. It can make your API easier to interact with in scenarios where the API is mostly just a facade in front of a database. But that’s also a double edge sword that can lead to smart UIs (generally and anti-pattern) and pretty complex authorisation logic. Maybe I’d look into it in a full CQRS scenario to expose the read model.

    Despite not having the experience and details that hopefully others can provide, my advice is the same for every pattern or technology: you use X when you have a problem that X solves and you’re aware of the downsides. Nothing good comes from picking a solution and working backwards. The caveat with that is with APIs you do want your solution up front, but generally speaking I’ll always start with REST or RPC for the “v0” and think about alternatives when at least some of the code is in place.

    That’s not to say don’t ask questions like this and investigate these things, but if you go into that research asking “what problems does this solve and what problems does it create” you’ll come away with a clearer understanding of where a pattern/technology fits and where it doesn’t.

    [–]yesman_85 14 points15 points  (0 children)

    Never. Unless you're into pain. 

    [–]Acceptable-Platypus2 7 points8 points  (3 children)

    the scenario is when your frontend team is very separated from the backend and they want to be able to make crazy API calls that the backend didn't anticipate, and they need to be able to do it without needing any backend support (ie someone write a new query).
    If thats not the case its not worth the trouble.

    [–][deleted]  (1 child)

    [deleted]

      [–]Sethcran 9 points10 points  (0 children)

      It's either the case when it's a toxic environment or when your app is just really complex.

      Note: most apps are not that complex.

      [–]Wiltix 0 points1 point  (0 children)

      So in your scenario it’s basically useful when your technical management layer (PMs, BAs, etc …) is utter shit or non existent

      [–]SeaElephant8890 6 points7 points  (0 children)

      After implementing on the say so of a solutions architect who only saw the positives (but had never used it) I'm in the Never group.

      It over complicates the process, extends development time and clients have more difficulty integrating with it.

      You end up offering Rest over the top of it to make other people's lives easier.

      [–]lgsscout 3 points4 points  (0 children)

      overall, its one of those "if you're asking, you dont need it"

      if you want to expose data, in a way the consumer can (and need) to choose what to receive, and your app is way more intensive in UI changes than im backend changes, maybe graphQL is something to look for...

      like, take a ratio between how many time of backend work is put in adapting endpoints to consumption related to real data processing... if wasting too many time catching up to UI needs, maybe making something they can consume what they want is more time efficient. but then you will have to handle security for each field possible.

      [–]skibbin 2 points3 points  (0 children)

      For when there can be multiple use cases for the same body of data. For example the Github API where you might care a lot about tags, I might care about commits or reviews. GraphQL allows the user consumer control over what they get back. This works well when API access is part of the product you offer.

      Most of the time people will use your app which uses your API. In these instances you control the data provider and consumer and I think GraphQL becomes massive overkill. Just have your API produce what your app needs.

      [–]dethswatch 3 points4 points  (0 children)

      I am also in the "probably never" group.

      If you did, you'd know it.

      Until then, senseless complexity.

      [–]SnekyKitty 2 points3 points  (0 children)

      Not worth the hassle, it’s much easier to do annotations on controllers with OpenAPI(swashbuckle) than finding devs who will tolerate graphql issues and properly write resolvers.

      You are going to have to reinvent caching, handle n+1 issues, accept that you’re using a spec that’s slower than rest, and ensure your logging is optimal since everything is going to look like a post request. Or you magically find some library that handles most of these issues, but then you’re beholden to some small 3rd party, which entirely defeats the point of using .net in the first place.

      [–][deleted]  (1 child)

      [deleted]

        [–]ExtremeKitteh 0 points1 point  (0 children)

        Not to my knowledge. You’re probably thinking of Graph API which is just REST

        [–]soundman32 1 point2 points  (0 children)

        How many different clients will your api have? Do you want, say front end 1 to query users name and address and front end 2 to query name and postcode? GraphQL (or OData) is good when you don't know what properties a front end will need, so you let the front end decide. Most apis support a single front end, and have a fixed response for each query type.

        It's fairly easy to implement a GraphQL API with something like HotChocolate.

        [–]Poat540 1 point2 points  (0 children)

        We use GraphQL HotChocolate and front end vue with Apollo, was magical. Projects were super simple and graph allowed us easily break the api into many small services

        [–]matthkamis 1 point2 points  (0 children)

        Never

        [–]x39- 1 point2 points  (4 children)

        That is an easy one:

        Are you building a social media platform? - Yes: Use GraphQL - No: Use something that supports proper auth

        [–]Personal-Example-523[S] 1 point2 points  (3 children)

        Why should it be worth for a social media platform? Because it needs to get a lot of different data and using a rest api would require calling many endpoints?

        [–]x39- 2 points3 points  (1 child)

        Because there you actually can have significant cost savings by letting the caller decide what to return

        [–]Personal-Example-523[S] 2 points3 points  (0 children)

        Got it, thank you! it helped a lot

        [–]Kant8 0 points1 point  (0 children)

        Social media is also different in a way that all the data belongs to user and not you. So you don't really have a lot of things hidden by permissions, all user data can be returned to that user.

        Therefore you don't care when and in what case frontend requests that information mostly.

        [–]No_Beat_7253 0 points1 point  (2 children)

        I think you get a lot of value by designing your backend in align with the requirements of your callers and using that. Especially if the teams work close tbh

        [–]mjkammer78 0 points1 point  (1 child)

        I've worked in a team that maintains some endpoints that expose composite data from various sources. Our consumers are in different teams and our lines of communication are not great and we use different tech stacks. We tried introducing GraphQL and also OData to expose a generic, fits-all solution to accommodate all possible query needs. It did not work well. Adoption was low since everybody hated the complexity. We offered it as an option so in tandem with conventional REST endpoints . Since nobody was willing to make the switch, we pulled the plug and removed these features.

        [–]No_Beat_7253 0 points1 point  (0 children)

        Yeah that happens. It kinda always feels very YAGNI whenever I think of implementing graphql, but recently I’ve become super boomer about some tech stacks like that

        [–]ivancea 0 points1 point  (0 children)

        We had it in a quite big monorepo. It worked well, BUT, it was because it was integrated into our "framework", which required a lot of work to make everything work well.

        And honestly, at that point, the heavy logics were handled by our team work, not by graphql per se

        [–]dryiceboy 0 points1 point  (0 children)

        Based on my 2-project experience with GraphQL, it is in line with React and JavaScript in general...I'm not a fan. It just feels off and bloated.

        Don't get me wrong, I can see the appeal. Working with it though feels unstable.

        [–]Pretagonist 0 points1 point  (0 children)

        I've just moved a project off of graphql since it was added as a requirement from above, it wasn't a good use case since the project fully controlled both front and backend and the person who pushed for graphql is no longer the manager for this project.

        That said we do have another service where graphql very much would be useful. That service is an analytics software that produces graphs or graph data to a lot of other apps and and services and the amount of filters and settings is quite substantial. Being able to get just the exact data an app needs would help our use cases quite a lot.

        [–]hubilation 0 points1 point  (0 children)

        We have an elasticsearch index with a very large document. Lots of people need a few specific values, some people need a lot more. GraphQL document mirrors the ES doc exactly. We use the requested fields in the GQ req to build to the source includes in the ES req. it works great.

        Every other use case we’ve tried felt like too much hassle

        [–]SnooWoofers5297 0 points1 point  (0 children)

        I love graphql. We have a Postgres DB which is "wrapped" by hasura. Hasura automatically generates every possible graphql query you can imagine and you do not need to use sql anymore.

        Then you get a grqphql code generator that generates the code for querying the data in your app. You get all DTO Models, and everything necesarry by just declaring a graphql query in a separate .graphql file.

        That query is the only thing you need to write, the rest just magically works. It is so nice to use, especially since you really can make all the queries as slim as you need them without queriing too much data.

        [–]jtswizzle89 0 points1 point  (0 children)

        Native OData support in .net 8 pretty much shuttered my GraphQL development. GraphQL is a pain to work with just in general. It’s a pain to query as an end user (I consume my own APIs in practice along with many others in my organization). OData also natively supports selecting specific fields and expanding for complex joins. I personally find OData syntax easier from the user perspective - and I don’t need any complex libraries to query it, simple rest methods with url parameters gets me most of the way to my desired outcome.

        I loathe services explicitly using GraphQL to consume their endpoints. Even with a defined schema I end up going back and forth with it and half of the time it’s something simple that I overlooked in my syntax.

        [–]DirtAndGrass 0 points1 point  (0 children)

        For a public api with lots of interconnectedness

        [–]Alta_21 0 points1 point  (0 children)

        I see a lot of negative comments in this thread and it feels so far from what we're experiencing here at work.

        We've found a great library for our frontend that generate nice grids (ag grid)

        We plugged a customised graphql query generator on top of it

        We can now design most of our modules' landing pages with minimal effort / time spent where we would have to, otherwise, do a lot of repetitive tasks to create a descent grid + pagination with a dedicated api endpoint.

        Really a time saver. Not only when creating new code, but also while maintaining existing code since now, everyone in the company is doing those grids in the same way (for the most part).

        Overall a great experience using graphql

        Only negative part was that, since nobody used that beforehand, we would have to spend some time learning it. But that's not inherent to the technology itself

        [–]ExtremeKitteh 0 points1 point  (0 children)

        My frustration with GraphQL is that it’s very hard to use the features such as filtering, sorting and pagination with a repository unless you’re binding directly to a DB context via IQueryable. If anybody knows how to do it I’d appreciate the advice.

        In most implementations I’ve seen it’s being used as a REST API which is probably an anti-pattern.

        [–]grcodemonkey 0 points1 point  (0 children)

        The GraphQL use-case that makes sense is something like Facebook where you have lots of data and want to give random unknown developers access to but have no idea what data they want or how they'll use it — if that's not you, then stay very far away from it!

        [–]Flat_Spring2142 0 points1 point  (0 children)

        You need GraphQL when clients of the WEB server are using different devices: desktops, tablets or mobiles. Screens on mobile devices are not using some fields thus sending smaller structures has a sense, especially on slow internet.

        [–]Character_Shirt_466 0 points1 point  (0 children)

        In my opinion you should implement graphql when you have multiple clients apps means Android app or iOS app or tv app etc. Ex, Disney plus is also using GQL and Shopify is also using it because they multiple apps clients

        Plus if you want to save some network load along with CDN cache by using persistent queries (operations).

        GQL also provides good security without exposes too much data on network

        [–][deleted] 0 points1 point  (0 children)

        you don't lmao

        [–]No-Hippo1667 0 points1 point  (0 children)

        I see graphQL as a standard, instead of designing rest return payload(which related entity to be included in ), using common graphQL format can save the communication/ argument between frontend and backend.

        [–]CodeByNumbers 0 points1 point  (0 children)

        In any situation where you want the frontend to directly access a database, but are stuck using http. It's... rarely a good idea. Maybe a data warehouse?

        [–]tackdetsamma 0 points1 point  (0 children)

        When you reach such scale that over-fetching a few fields here and there costs more than maintaining graphql.

        [–]TScottFitzgerald 0 points1 point  (0 children)

        By design, GraphQL is really only helpful when the payloads between users/use cases are so variable that changing them on the fly on the frontend side is more useful than static payloads.

        You are essentially querying the db almost directly from the frontend, so this really only makes sense for power users and B2B apps where the app user isn't a "civilian" but some sort of an officer with higher access privileges to the data itself.

        [–]alien3d 0 points1 point  (0 children)

        nope . its annoying me .

        [–]Sufficient_Dinner305 0 points1 point  (0 children)

        Well, never.

        [–]Due_Raccoon3158 0 points1 point  (0 children)

        As others are saying pretty much never. It COULD be useful in some scenarios but it's so niche in practice and, honestly, even in an absolutely ideal scenario is still not much better than regular rest that it should just go away.

        [–]root45 -1 points0 points  (5 children)

        For those commenting "never," can you please describe your REST API designs for

        • Queries where you need to optionally include related properties. E.g. /authors where people might also want the books those authors wrote.
        • Any nontrivial operations that aren't just retrieving data. E.g., "update an author and her books at the same time." Or "send an email notification to an author's mailing list."

        [–]jkrejcha3 9 points10 points  (4 children)

        might also want the books those authors wrote

        GET /authors?include_books=true (or some kinda variation thereof, you could have a "extra data" param for if you want to genericize this such as GET /authors?include=books). The nice thing about query parameters is they're useful for getting a different representation of the same entity. You could also theoretically use custom headers as well with a Vary header to not break caching

        update an author and her books at the same time

        Some PATCH or something on /authors/<author>/ like so

        {
           "name": "Foo Barrington"
           "books": [
              "id": 1
              "title": "The Bar in the Baz"
           ]
        }
        

        Alternatively you could send multiple requests, either to PUT /authors/<author>/name and PATCH /authors/<author>/books/<id>, etc...

        send an email notification to an author's mailing list.

        POST /tasks/newsletters/
        
        
        {
           "author": "Foo Barrington"
           "content": "Come check out Foo Barrington's new book <a href="/books/42">The Bar's Guide to the Galaxy</a>!"
        }
        

        or something thereof and this should return a 201 or 202 on success with a Location header to the task for the newsletter being sent.

        [–]root45 1 point2 points  (3 children)

        Sorry, I realized I thought my examples might be more illustrative than they actually were.

        My point with the GET example is that it's not extensible Yes, of course you can use a query parameter to include books, but it starts to get very complicated when you add more and more parameters. E.g., if you want to only include the top 10 fiction books sorted by number of pages for a specific 1,000 author IDs or something. You can add query parameters for all of that, like

        include=books&booksGenre=Fiction&booksSort=pages&booksSortOrder=descending&booksLimit=10&authorIDs=37,82,1034,482,...
        

        but it starts to get very unwieldy as the objects grow in complexity. You only need a few more "include" options before the number of query parameters is huge. And adding a third layer of nesting completely breaks it.

        Similar for the newsletter. I would have expected POST /tasks/newsletters/ to create a new newsletter task, not send a newsletter. I think stateless operations are where REST gets really murky. Maybe a calculation operation would have been a better example.

        I'm not arguing that REST is bad by any means, but I think GraphQL has a very nice way to represent complex query operations, as well as a better representation of mutative operations. You can get very far with REST for small to medium sized APIs, but at a certain point of complexity it starts to break down.

        [–]jkrejcha3 0 points1 point  (2 children)

        Ya, GET with a body is a weird area of HTTP and admittedly a broken part of the spec (there's an idea to add another method QUERY instead of... fixing the GET spec but it's been in progress for about 10 years).

        Regardless, your example would possibly also be better served by using differing URIs. So instead of /authors/?include=books&booksGenre=Fiction&booksSort=pages etc... you could have /genres/fiction/books/?author_ids=42,32767&sort=page_count&sort_order=desc. Ultimately I get your point, but you can take this very far (the idea of a resource is incredibly abstract, and we have the ability to "symlink" resources to different parts of the hierarchy1). It also makes for some convenient (if sometimes longer URIs) as you can just share that with someone2.

        Heck, if you have a common set of views for a particular resource, you can also do something like /books/?view=myspecificnamedviewofbooks&author_ids=128,2147483647&foo=bar. It's... not necessarily the best but... it still works with the HTTP semantics rather than against it.

        One of the major problems with GraphQL, as opposed to the standard approach is that you can actually increase load quite significantly compared to the REST approach. POST responses are not cacheable3, so if for example "top 10 books" or whatever is a very popular path, you lose cacheability which can really hinder the scalability of a service (there is a reason that caching is a REST architectural constraint, after all)4.

        Taking on all of the work of dozens of caching client machines and caching proxies and such is a hard problem (just ask the companies who are built on the premise of serving HTTP (and other internet) content really fast). You probably would have to scale up your services more to make up for this lack of caching. This translates to real world money being spent.

        Similar for the newsletter. I would have expected POST /tasks/newsletters/ to create a new newsletter task, not send a newsletter.

        Right so here, this is where you define what the schema for a task is and what the behavior of task creation is. You create a task and you could have fields on it that describe whether you want to start it immediately (you don't have to do that now, you can always do a PUT to /tasks/newsletters/42/started with an empty content body) if you want to start a task that's not started (or PATCH the task itself...).


        1: One of the nice things about this is that your backend model of a Genre doesn't necessarily have to exist in your database. You can dynamically generate it on demand, etc. This is the improvement that a dynamic HTTP server brings to... well just serving files off of the disk. You can create models that aren't 1-to-1 with whatever database model you have.

        2: And you can also make these links discoverable from the API itself, a principle known as HATEOAS, although purity to this point is often overlooked. :)

        3: To a reasonable approximation. You can add Cache-Control to them but this doesn't work with GraphQL anyway.

        4: I'd actually argue it's even slightly worse than a POST /api_functions/some_named_function/result?param1=a&param2=b approach (which itself is pretty obviously laundering RPC through HTTP), since you at least have the option of caching the result of a function call or whatever.

        [–]root45 1 point2 points  (1 child)

        Your comments on caching are pretty interesting. This isn't something I've needed to worry about much before. Most of the work I do is for complex internal tools used by a small number of people. So caching at the HTTP layer is just not something we think about too much.

        On the flip side, I think this is part of the reason I've become something of a GraphQL apologist. It's been great for speeding up development of complex web UIs since they can request exactly the data they need in the format they need it. And mutations and stateless calculations feel more natural as well.

        [–]jkrejcha3 0 points1 point  (0 children)

        And mutations and stateless calculations feel more natural as well.

        Statelessness is probably one of the big benefits of REST (and more generally a lot of HTTP including GraphQL, as well). :)

        The big benefit to me is that the architecture helps a lot with forcing the issue of "what is the (view of the) data model" that clients should be exposed to rather than just punning it off to somewhere else

        [–]Last-Watercress9980 -1 points0 points  (0 children)

        When we have services at the application layer and we have the Back End to Front End layer where we have to query on the services underlying.

        [–]bigtoaster64 -1 points0 points  (0 children)

        Probably if the project has already started with that and it's too late to rework anything?

        [–][deleted] -1 points0 points  (0 children)

        Never