Hacker News new | past | comments | ask | show | jobs | submit login

I never understood why people go for graphql.

In my experience, it's a nightmare to 1/ secure 2/ version 3/ ensure qos

Securing it properly should make it a no-go in like 95% of cases. you get amazing flexibility on the front end with a heavy heavy cost on the backend. Also, in general being able to say "i want to do whatever" and request everything at once is an anti-pattern IMHO, especially after HTTP2 became mainstream and doing multiple requests is reasonably fast.

Versioning? Forget about it. Now you have "all the versions" and good luck figuring out what is used, what is not used or god forbid deprecate something. you're going to have a bad time.

As far as qos goes, if any client can range from "i'm asking a simple thing" to "i would like the whole world please - and btw you're only going to figure things out as you pull them in" qos becomes a pipe dream.

Last, I don't understand what Netflix does that is so complex that would warrant something like gql. I just don't. To the naive developer in me it seems that they 1) need to have a basic api to get whatever catalog they have + a few apps build on top of that 2) have figured out how to do streaming exceptionally well in order to scale to all the people watching. That's is and although a gross oversimplification I cannot think about a scenario where gql is needed.

I think in their desire to reinvent the wheel Netflix has jumped the shark. A lot of really good ideas have come out of the innovation they did in the past but lately it seems like they are doing things for the sake of doing them or they are pissing people off with password household policies and whatnot.




Going to reply here because, as a huge fan of GraphQL, I strongly disagree with every single one of your points. To start, I think the biggest misconception I see about the value of GraphQL is people see it as some sort of generic "query language", which is unsurprising, given the name. If anything I think the biggest problem with GraphQL is that, if people just saw it is a simple alternative to REST, with a well defined set of query (GET) and mutation (PUT/POST/DELETE) endpoints, they wouldn't get caught up in all this "infinite object graph" stuff that I never hit in my day-to-day.

To your points:

1. I find GraphQL to be fantastic for security, primarily because all calls are strongly typed, so you can ensure by the time a request gets to your resolver it is guaranteed to match the defined input types. Furthermore, I always make heavy use of custom scalar types instead of String, which allows me to get rid of a whole host of potential security issues by limiting potential injection attacks before my code even sees it. As far as ensuring object ownership/permissions, this is trivially easy, or in any case just as easy as with REST.

2. Versioning is one of GraphQL's greatest strengths. The tooling makes it easy to deprecate some fields while adding replacement ones in a way that guarantees backwards compatibility. Far from "good luck figuring out what is used", the tooling e.g. in Apollo makes it very easy to see which clients are making use of which fields. Furthermore, if you do need to "hard version" a new endpoint, you can do it similarly to REST by including a version parameter in your URL (e.g. /v1/myGraphQLEndpoint).

3. Regarding qos, this again just gets to my original point about having well defined queries and mutations. Your queries don't need to say "allow me to see the world" any more than any other API framework. It's not hard to just have queries that only say "give me X by ID" and also a single bulk retrieval endpoint where you define the boundaries of what you want to return.

If anything, I think perhaps a lot of misconceptions around the problems of GraphQL have to do with these tools that basically say "expose my whole DB with GraphQL", which in my experience usually leads to tears in the end.

But starting with a thoughtful definition of your API surface area with GraphQL's type definition language can make it a joy to use and provides lots of benefits over a straight RESTful interface.


>If anything I think the biggest problem with GraphQL is that, if people just saw it is a simple alternative to REST, with a well defined set of query (GET) and mutation (PUT/POST/DELETE) endpoints, they wouldn't get caught up in all this "infinite object graph" stuff that I never hit in my day-to-day.

But isn't this "infinite object graph" like the only real valuable part of GraphQL? People get caught up on that because all the other things you mention aren't really an issue with normal REST API.

If you're saying you use GraphQL but don't use the key defining feature of GraphQL. Then what's the point of using GraphQL if you're just using a strict predefined set of things you can query/mutate?


Value of GraphQL imho is the ability for the api to be driven by frontend requirements without bothering the backend guys "to expose that one field in that one query".

Once the app is developed I think you might put up reasonable general limits to what queries are responded to in a general manner over the whole api.


This is how I have interpreted its value, and frontend devs have very plainly advocated for its use with this argument. I think this is a really silly value prop.

Behind the elegance of a query language that lets you get your perfect little payload, there is a complex server that could need to resolve and block on requests to multiple backends, touch different caches and databases, and do joins and sorts and projections. Front end devs will add the videoRating field and have no idea that this comes from a separate API and causes the response time to double.

Developing some gragantuan do-it-all meta API as a sandbox for frontend engineers is a terrible idea. You don't just slap a graph over your APIs and call it done. The GraphQL server is orders of magnitude more complex than a purpose-built API.

Ultimately once the FE devs have crafted their query to satisfaction it will hardly ever change. It's better to work together and decide whats needed and how to best get that data to your app.

I really favor collaboration on purpose built APIs than gargantuan do-it-all systems.


"Driven by frontend requirements" is how approximately all APIs in the world are developed. The problem GraphQL exposes, and makes extremely punishing when you ignore it, is that of poor communication of requirements.

Put it this way: you _could_ build a GraphQL resolver by means of mirroring your database schema or service structure, and let frontend engineers play in that sandbox while patching up holes. This would have the exact same result as building a REST API service that proxies requests to a SOA without understanding the performance or stability impact. Or the exact same result as exposing multiple REST services that must all be hit to render a single screen on the frontend, except you push the blocking to clients, which is not a proper solution if you care about the energy usage you don't pay for.

In all of these cases, the common thread is that the backend and frontend teams aren't working together and thinking of the entire product as a system instead of a frontend/backend split. GraphQL forces you to reason about the entire system and not a series of API calls, which can obviously cause problems with siloed teams.

This means I disagree with folks who attribute the power of GraphQL to "frontend-driven" APIs. Your frontend and backend is your product, so ultimately you must reckon with the boundary layer between the two.


This whole thread makes me happy that at my job we don’t have this arbitrary backend/frontend split. Everyone on my team does both—if you are working on a feature you implement all the parts needed for it. Seems like it avoids a lot of this coordination hassle.

Of course some people are better at one or the other so for very tricky things we might have them take over those pieces. But 99% of coding is fairly straightforward.


It's neither an arbitrary split, nor is the fact that everyone does both exempt you from this discussion. You are still concerned about this, unless you are doing some desktop app.


The thing is there are solid, replicable patterns for optimizing graphql. The way we use GraphQL is to expose "everything" to the frontend folks so they can work closely with design until they have a polished frontend for whatever they're building, then our backend folks look at it in APM in Datadog and figure out where to optimize it. Once we have an optimized query, we ship it. Everyone's aware of the basic optimization patterns we use, and backend is a pretty well-oiled machine.


> Ultimately once the FE devs have crafted their query to satisfaction it will hardly ever change

this makes the fallacy that it is FE devs driving change. it is not. it is product management. and to them (and indirectly to you), making it easy to make performant changes without 3 committee meetings is a Good Thing


This is a problem with siloing front end development, not graphql.


> Front end devs will add the videoRating field and have no idea that this comes from a separate API and causes the response time to double.

That's absolutely wonderful problem for the backend and db teams to detect and solve. Cache it, use another data structure, pre-calculate, build cunning indexes, if you can't do anything just throw hands in the air and say it cannot be done. Neither frontend team nor the client does care about backend woes. And frontend team doesn't want to be kept in the game of telephone as backend negotiates solutions for performance with the client.

That's what GraphQL does. Provides better separation of responsibilities between the teams and lowers the amount of conflicts and delays because of the reduction of verbal communication necessary.

> Developing some gragantuan do-it-all meta API as a sandbox for frontend engineers is a terrible idea.

It's not a sandbox for developers. It's for the clients. I know it's painful for the backend developers that front end doesn't want to be involved in challenges to the backend caused by customer's requests and how often they change. GraphQL makes those problems owned by backend devs and noone else.

> I really favor collaboration on purpose built APIs than gargantuan do-it-all systems.

Same as with the software itself, well separated parts, clear non-overlapping responsibilities, small, well defind interfaces between the parts result in better outcomes.


So you move the issue to the resolver instead? IMO graphql is trying to allow the frontend to be the 'driver', the first bit; otherwise you just have the backend publish an API and then that is what it is, if that one field is available from a different endpoint than the one you're currently using, that's the one you need to hit (as well), tough.

Not to say either way around is inherently better, I just see it as a switch from backend-driven to frontend-driven.

(Personally I'd love to use something like OpenAPI, with tooling more mature than probably exists, to be properly schema-driven, with both backend and frontend stubs/clients derived from that.)


> So you move the issue to the resolver instead?

Yes. Where it can be logged, inspected and dealt with wholesale.

It's moveing a problem from intra-team verbal communication into software where it can be dealt with more efficiently with software tools and methods.

> Not to say either way around is inherently better, I just see it as a switch from backend-driven to frontend-driven.

Yes. I think that's the whole point and main benefit of GraphQL which makes a lot of sense since apps that evolve through their development usually have most changes UI driven.


> Where it can be logged, inspected and dealt with wholesale.

Just as it could be in the backend? I don't follow that point.

> apps that evolve through their development usually have most changes UI driven.

That's a fair point certainly, but isn't completely generalisable - if you offer a third-party API at all (or think you might) then maybe don't special-case your own frontend.


> Just as it could be in the backend? I don't follow that point.

GraphQL server is the part of the backend.

The problem is that client has a new requirement, it is verbally communicated through UI change request. Frontend team implements the change then has to make a verbal request to the backend team for new data to be exposed. There's a bit of back and forth, testing. Everybody waits for everybody. It all takes time and is most of the time brainless busywork. GraphQL makes it so that request to the backend team doesn't need to be verbal (jira is same as verbal for me). It can be mediated through software and even fulfilled automatically if the GraphQL server is open enough during development. The cost of that streamlining is that at some point security or performance issues might arise, but those then can be dealt with solely by the backend and db team, as they should be because frontend is always insecure.

> if you offer a third-party API at all

For one such app 99 have both server and the client developed in sync.

And even then with offering third party api I think it's way easier to fall into the trap of special-casing your frontend with poorly designed REST than with GraphQL, althought there might be performance and security challenges as there always are with anything public. So there might be a bit to learn about how to deal with that in GraphQL ecosystem.


> It can be mediated through software and even fulfilled automatically if the GraphQL server is open enough during development.

You pretend that GraphQL is magic.

If there's requirement not exposed by the GraphQL server, the way to add it is literally exactly the same as for any other backend API.


Sure. But it's magic enough for me if I don't have to create a ticket for adding existing database field to a DTO every single time.


> But it's magic enough for me if I don't have to create a ticket for adding existing database field to a DTO every single time.

It means that those fields are already exposed to you by backend. Had they not been, no amount of magic on your side would make them appear.


So you've reached a point where working together collaboratively is such a burden that you've adopted technologies to circumvent that activity.

This suggests that GraphQL adoption is a sign of impending business stagnation. This does in fact align with my experience around GraphQL.


> So you've reached a point where working together collaboratively is such a burden that you've adopted technologies to circumvent that activity.

On braindead busywork, yes. Please automate everything about it as soon as possible, including communication. I don't want to collaborate on it with a human the same way I don't want to collaborate with a human on my McDonald's order and I prefer to access their ordering software through a kiosk or a phone.

> This suggests that GraphQL adoption is a sign of impending business stagnation. This does in fact align with my experience around GraphQL.

That very well might be. But stagnation understood as predictably churning an app after an app.


In my experience, braindead busywork is largely non-existent. Yes, there are times when you'll have to do something easy that conforms to code requirements and standards. But when the frontend needs to update something that is coming from a server, there is a real opportunity to discover, illuminate, and even solve architectural issues.

Sometimes that solution is to use GraphQL to make it easier to manage client implementation fan-out and requirement diversity. But GraphQL is never a substitute for communication and collaboration.


> In my experience, braindead busywork is largely non-existent.

Lucky you. In corporate environments I worked at it took easily half of the time.


So this completely contradicts your GP post who says the fact that it supports generic queries is not the point of GraphQL.

So which is it?


Generic during development. Once the dust settles you can restrict to what's used.


If you have 1, maybe 2 front ends then this is flat out laziness.

The front end arguement makes sense for someone like Facebook who has many different front ends and integrations. It’s unmaintainable to try do this any other way.


This is helpful, but it confirms my sense that a REST API with a typed spec like OpenAPI is going to get you basically all the benefits of GraphQL.


Pretty much, they are fundamentally both RPC flavors, so it's impossible for them to have different properties beyond more or less convenient tooling. It's always jarring to see those heated GraphQL vs REST APIs (as implemented in practice) vs gRPC discussions as if they are as different as, say, client-side CRDTs.


> Pretty much, they are fundamentally both RPC flavors, so it's impossible for them to have different properties beyond more or less convenient tooling.

REST arguably has better support for catching for read queries.


Pretty much except writing graphql schemas is actually quite enjoyable and expressive. I was always the biggest advocate for schema-first development, but OpenAPI specs were always such a pain to write and maintain. For this reason alone I would choose graphql (yet there are other benefits).


I agree, the schema language itself is very nice. The trick is to use a web server framework that generates the OpenAPI spec for you.


While taking half the time to do it.

I've yet to see one good reason to use GQL for anything but public facing APIs, like GitHub API.


If I'm understanding correctly, there is a lot more work a team has to do to build and maintain a GraphQL API and should only do it if they understand what they're getting into and what its advantages are. It's not for everyone, and everyone shouldn't assume it's for them.


> there is a lot more work a team has to do to build and maintain a GraphQL API

I wouldn't say that. It's simple and straightforward to get around some pitfalls of GraphQL, if you treat it as an enumerated set of RPC-style endpoints.

The commenter I was replying to stated "Thr fact that you're arguing that it should not be treated as a generic query language when it's in the name and this is how it's sold is hilaruous". Perhaps so. By far the biggest mistake I think the original designers of GraphQL made was putting "QL" in the name, as many people think it's in the same category of tools as SQL (I heard someone ask once on HN "Can you do joins in GraphQL?", which isn't even a question that makes sense). It should be treated as a competitor to OpenAPI, and there are reasons why I would prefer using GraphQL in many scenarios.

I think I'll probably write some longer form blog posts at some point about how I think GraphQL is easy to set up and get running quickly, and how to avoid some common misconceptions.


> By far the biggest mistake I think the original designers of GraphQL made was putting "QL" in the name

No. The biggest mistake why not emphasising to people the usecase they solved which was having many many different front end consumers and having to create many permutations of the same endpoints to cover web, mobile, various applications in different states, time to deliver endpoints to the teams. Etc

Most people are not working on the same number of implementations that Facebook or similar need. But they want to be on the bandwagon.


> It's simple and straightforward to get around some pitfalls of GraphQL

It isn't

> if you treat it as an enumerated set of RPC-style endpoints.

It's not that.

> I think the original designers of GraphQL made was putting "QL" in the name, as many people think it's in the same category of tools as SQL

"GraphQL is a query language for APIs" is literally the tagline at https://graphql.org/

And the frankly insane complexity of GraphQL comes from the fact that you now have to implement that query language, often over completely different sources of data.

Which leads to frankly inane solutions like the requirement to inspect the full request and the full response on the fly just to be able to cache responses.


This!

But I'll add one more: "Standardisation". Every RESTful API uses different URL paths, naming schemes, HTTP verbs, data structures, headers. Whereas those are defined by the GraphQL spec.

When consuming or creating a GraphQL API, those (usually meaningless) decisions are defined by the spec, so I only need to learn how the data is structured. Since it's a spec, my queries can be strongly typed in both frontend and backend.


I don't understand what you are saying here. RESTful APIs are supposed to follow a specific format, e.g. GET: candidate/{id}, GET: candidate, POST: candidate, body: CandidateDto, etc. How is GraphQL different? Keep in mind that you can "see what's available" on a Swagger page easily with a REST API.


For the security comment, I was thinking they were talking about authorization.

According to GraphQL, authorization belongs in the business logic layer[1]. A lot of projects ignore this advice and put it into the resolvers. This decentralized approach can be difficult to maintain and keep correct.

[1]: https://graphql.org/learn/authorization/


> if people just saw it is a simple alternative to REST, with a well defined set of query (GET) and mutation (PUT/POST/DELETE) endpoints, they wouldn't get caught up in all this "infinite object graph" stuff that I never hit in my day-to-day.

Can you explain this more? How can you avoid infinite graphs? If I have User {things: Thing[]} and Thing {owner: User}, you have to deal with this issue.


I have been writing GraphQL APIs on and off for the last 5 years, and in practice haven't had many scenarios where this was an issue.

In GraphQL the query for the example you gave could look like this

  ```gql
  query {
    user {
      things {
        owner {
          id
        }
      }
    }
  }
  ```
When resolving an array of type `Thing` for the `things` field, you would query for the user that the `owner` field represents. Rather than assuming all relations should be loaded for an owner by default, the client would specify the fields for the `owner` that it needs. Such as I have above for the owner id. Even if no fields are specified, it would be weird to assume all relations should be loaded by default.

Now if your developers are intentionally creating infinitely deep queries, then you'd solve this the same way you'd solve an infinite loop in your code today. An issue you would catch during development or CI/CD. This can be easy to catch using a linter or during review.

  ```gql
  query {
    user {
      things {
        owner {
          things {
            owner {
              things { } # etc
            }
          }
        }
      }
    }
  }
  ```
To simply protect from bad parties / developers, you might use something like https://github.com/slicknode/graphql-query-complexity

In addition you could introduce CI tools to enforce your devs stop writing such complex queries. Also see the @skip and @include directives that can further be used to control what data is queried. In practice, however, this isn't something that comes up too much. In cases where I have seen this happen, it's usually because a developer is trying to reuse fragments without considering what data they are querying, and whether they should be reusing those fragments.

https://graphql.org/learn/queries/#fragments


> In practice, however, this isn't something that comes up too much.

In practice this is an issue for any publicly exposed GraphQL API.

That's why the only solutions to the issue are to:

- either deserialize and deep inspect the query to try and figure out if it's too complex

- or to only expose persisted queries, turning it into a bad replica of JSON RPC.


Not sure it this is a great reply. Some valid concerns were raised, and in summary all you are saying is GraphQL is awesome because it has types, schema and defined queries / mutations. This is of-course the basics of GQL, there are a lot of complexities under the surface.

GraphQL does add some risks IMHO, e.g. client can send a really complex query (even a recursive one, e.g. get accounts for user, get user for each account). We cannot say this will not happen as we define the queries ourselves, since sometimes the API is exposed to clients which are not in our control. Queries can be sent which can almost bring a server down, so you need to handle that.

Also error reporting / handling is trickier as compared to REST (e.g. https://the-guild.dev/blog/graphql-error-handling-with-fp).


I think you misinterpreted the security aspect.

I assume what they meant (and what I mean when I talk about how dire security is on GraphQL) is visibility first and foremost. Which users have access to which data. Things like multi-tenant or even just “you have access to X-model or this specific field on this model”.

Couple that with inconsistent performance (at least for RDMS) and inability to make use of state stores in a sane way (IMHO) on the frontend makes it a non-starter.


[flagged]


> So in conclusion, you're moving the goalposts and asserting that everyone that has issues with the tech must be an idiot since it works for you.

That's not what GP asserted at all. You made some vague statements about gql, and they refuted with very concrete arguments.


I didn't call anyone else an idiot. You don't actually seem to be open to hear about how people can use GraphQL, in production, to solve a host of thorny issues that "plain REST" APIs commonly have to deal with. Congrats on your intellectual superiority.


> Falling back to arguing about typing show me that maybe you are not aware of the many interseting ways you can get screwed or maybe you just worked on simple straightforward things.

Please provide a few examples of this.


Since I'm not going to type a novel here is an example: https://wundergraph.com/blog/the_complete_graphql_security_g...

Also look at hackerone:

https://hackerone.com/hacktivity?querystring=graphql


Both REST and GraphQL API's can be well designed, or badly designed. While I'm a GraphQL fanboy, I would much prefer integrating with a well design REST API over a badly designed GraphQL API.

Having spent over 15 years integrating with, and writing API's, GraphQL was a breath of fresh air! If you think of GraphQL as a query language, you will find it frustrating. If you think of it like you do a REST API with all the ugly pain points straightened out and standardised, then it is a dream to work with.

GraphQL is as much of a query language as REST is. For example, most REST API's end up getting super long lists of parameters in their urls. How many eCommerce API's end up having REST URL's like:

/api/products?category=guitars&include_variants=true&page=20&per_page=100&exclude_fields=description,specs

Whereas, GraphQL transforms that into a simple, readable query, which does not require reading pages and pages of documentation to understand.

But, if you are creating well designed REST API's, I would prefer to use them over somebodies poorly written Graph.

Just like a REST API, a well written Graph should be crafted to be fast and performant to execute. Just like with REST, a Graph designer needs to sit down and think about the ways people will want to use the API. A good graph does not allow endless relationships that will cause performance to blow out.


/api/products?category=guitars&include_variants=true&page=20&per_page=100&exclude_fields=description,specs

Seems pretty readable to me.


Also, url query parameters are kind of orthogonal to REST vs. GQL.

They can complement either API. From personal experience, choosing not to use them (as most single page web apps don’t) can make testing painful and makes deep-linking to specific states of your webpage impossible.


> GraphQL is as much of a query language as REST is

This doesn't make any sense, unless it's to point out that GraphQL is not a query language at all.


> I never understood why people go for graphql.

It allows a full separation of the frontend dev velocity from the backend velocity.

The frontend is no longer dependant on backend engineers for API creation, nor negotiations on how those should look.

The backend can choose to observe the hot path of GraphQL and optimise those for your #3, but #1 and #2 don't differ from, say, REST.


So you're solving an organizational problem by using gql? Who needs proper authz/authn, security, scalability, sanity, qos if we can have frontend dev velocity? Checks out.


Solving organizational problems is a core component of any software you design in any organization that's not a 100% flat startup unfortunately.

> "Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure." - Melvin E. Conway

It's unavoidable. You can bury your head in the sand about it and demand that the technical structure only match your technical requirement, but then the organizational structure of the company will grind to a hault. People will always be people. Just because you give some of them a title like "Engineer" doesn't mean that we won't conflict on people problems.

Entire concepts like event driven architectures or microservices, while might have plethora of technical pros/cons are mainly pushed by management for their non-technical aspects. One of their main non-technical pro is organizational. If your component just emits events, handles events, and is implemented as a separate microservice then you can always just insert a team, or move a team in an organizational structure while minimizing the overall impact to a project.


> So you're solving an organizational problem by using gql?

Yes, of course! All problems are organizational problems at scale. I have no great love for gql, but painting it as a black and white decision pitting FE velocity against all other engineering concerns (including hyperbole like "sanity") is childish. There are legit tradeoffs discussions to be had, but if you think it's impossible to secure or scale gql then you're not a very imaginative or resourceful engineer.


Don't we solve organizational problems with software all the time?

Git Monorepo vs Polyrepo Microservices vs Monolith Kubernetes


Reminds me of Conway's Law, which states that the structure of your systems will mirror the structure of your organization.

https://en.wikipedia.org/wiki/Conway%27s_law


See also: Reverse Conway.


The simplest way to add auth is to read a user session and provide it in the context, and then do the logic in the resolver for access control. It's not any different from how you would do it in a regular REST based server and GraphQL certainly doesn't do anything specific to get in your way about it. Not sure why people keep bringing auth and scalability into it. Clearly facebook invented and uses it for the purpose of auth and scalability.


GraphQL really needs a gateway like Envoy to give better observability / control / auth, and indeed that’s how lots of people deploy it.


Okay. Tell me how you do the control/auth and allow certain users to access a resource while others do not access it while they may formulate complex queries where they ask for the kitchen sink.


By wrapping the code that loads data with code that checks whether the current (i.e. requesting) user is allowed to load that data. I don't really understand the problem, how is this any more difficult than any other API paradigm?


I think the additional issues come when you want to define access by a relationship instead of just the entity, which means you need to check access based on the edges, and not the nodes. You'd have to do this anyway with REST, but I think it's easier in some ways to make mistakes and allow more access than intended.


I honestly don't understand the complaints here. In our deployment it's implemented as an HTTP handler right next to all the REST ones and gets all of the standard authz/authn/obervability wrappers. It's allowed us to focus more on core development because the schema was exported over a year ago and hasn't changed much. It functions almost identically to the REST components but is easier to develop against. No issues with scale or performance that aren't apparent in the REST components either.


> Tell me how you do the control/auth and allow certain users to access a resource while others

how would you do this with REST? or any other kind of API? graphql, at it's core, is a tool for the frontend to describe to the backend what data it wants. how the backend replies to that is completely up to the backend.

> formulate complex queries where they ask for the kitchen sink

most concrete implementations i've seen include a way to limit complexity. in `graphql-ruby` for example, you can limit how many nodes, and you can apply a "cost" to a particularly expensive-to-calculate node if you like. Say you give an API only 10 "complexity points". You could make most nodes cost 1 point, and expensive nodes cost 3 points. Now, someone can _request_ the kitchen sink, but you can respond with a "no".


https://konghq.com/blog/engineering/graphql-authorization-at... has a pretty comprehensive look into one way to handle auth with Kong. I believe Envoy can do something similar. It’s not as easy as an htaccess with regex on routes but it’s not impossible.


This is handled at the library level, typically. For example in graphql-ruby, it’s built in [1]

[1] https://graphql-ruby.org/authorization/visibility.html


Honestly there’s a few good ways to do that. Schema directives, regular old permission system at the resolver level, etc.

I’m not a big fan of GraphQL, but I it’s not particularly difficult to secure.


Is it not possible without Envoy? IMO this feels like a failing if I'm relying on a separate piece of software. I'm comparing it with RESTish services which are easily scaleable in many ways either software or infra. But that might be my misunderstanding of what you just said


It’s something that’s handled a lot these days at BigCos by service / query gateways / proxies and in the places that utilize these heavily it’s pretty automated from my experience. Basically the dev experience is you go into some web ui or make a PR against some JSON / yaml policy to allow whatever then it just works because some other sec / infra team plumed in all the auth and access control parts.

GQL itself doesn’t attempt to solve authZ or authN by design.

Edit: if you want to do this with nginx or within graphql / express, this is what that could look like https://www.apollographql.com/blog/backend/auth/a-guide-to-a...


> frontend is no longer dependant on backend engineers for API creation

So long as the backend engineers at least anticipated all the relationships, properties and objects that the frontend might ever need?


What? And who is writing and implementing the GraphQL schema??

I work on a GraphQL backend and I can tell you, every time the UI needs some new fields we don't have in the GraphQL schema, I've gotta go and implement that just like in REST, the fields don't magically materialize into existence.


Except when it’s not performant, and then suddenly you need those backend guys again!


If GraphQL is set up correctly ie through Apollo Server or other server implementations which implement performance optimizations, backend people will never have to touch it again, yes.


“No true Scotsman” fallacy surely? Yes, in theory, but in practice, all sorts of issues like the N+1 problem can pop up


In Apollo server you can add directives to your scehma for authz. It's dead simple.

I'm surprised how so many HN posts about graphql just slander it. If you go to the website and look at the use case of why it was made, it makes it pretty clear when it could be a good to use. My experience with it has been very straight forward and a joy


For me it was the prevalence of GraphQL that was annoying. I have worked with it and liked it as a technology, but it was a tell from the org I worked for an was definitely overkill for what we were doing. No matter how you slice it, GraphQL is added complexity compared to REST but of course, as with a lot in our industry, there are all the people bought in who put in the time to learn it who are going to shout, "Naw, it's easy!" To be clear I'm not saying GraphQL is super complex, just more complex than REST and if all you need is REST then that is what you should be using. Yet in my many interviews over the past year I talked to a bunch of companies who used GraphQL and I'd say, "Oh, cool, why did you choose it?" and they'd say something along the lines of, "Well, the CTO who wrote the original app thought it was cool at the time." So I've always got the impression that the backlash mostly comes from the huge evangelism it got making it out to be The New Way. Again, to be clear, I'm not saying it was marketed this way but it's how it felt at the time. Annnd again, I know this happens constantly in our field.


GraphQL (as in the language spec) offers no way to perform authz. Just because there are non-standardized extensions out there for some languages, doesn't mean it is available in whatever language you're using.


Ok, but that’s true whether or not you use GQL.


Sure. I could respond with a 4xx code because you’re not authorized for that field. Ah, but maybe you want to know which field? Too bad GQL doesn’t really support that.


GraphQL has strongly typed errors unlike REST. It is very akin to the Result type in many languages in that you are forced to handle errors even when writing the query, and the query will simply not compile if you don't.

For example, the Pothos library implements this pattern automatically:

    type Error {
      message: String!
    }
    
    type Query {
      hello(name: String!): QueryHelloResult
    }
    
    union QueryHelloResult = Error | QueryHelloSuccess
    
    type QueryHelloSuccess {
      data: String!
    }
    
This field can be queried using fragments like:

    query {
      hello(name: "World") {
        __typename
        ... on Error {
          message
        }
        ... on QueryHelloSuccess {
          data
        }
      }
    } 

https://pothos-graphql.dev/docs/plugins/errors


But now I’m most likely returning a 2xx response. There are asshole corporate middle boxes somewhere that will cache it. If I return a 4xx response, from experience (albeit nearly 5 years ago) I’ll crash your client. Now what?

If someone has solved the asshole corporate middle box problem using GQL, that’s really good news.


Authorization errors can go in the errors array which has a path reference in the standard.

You generally don't want to use HTTP error codes with field level errors in GQL.


So still a 200? Or a 202, 206, 207?


401 or 403. Why is this a question?


Because there may be fields requested correctly alongside some requested incorrectly


Outside of very few cases it means the request was incorrect.

And bo one is stopping you from returning a response that contains error details.


[flagged]


My SaaS backend is a GraphQL Server that has single-handedly saved me tons of hours for integrations and coding. The first iteration of the app was using rest and that was a pain. Hitting multiple endpoints to get all the details of an order is not something I miss. On top of that, I get a beautiful playground that acts as a query builder and documentation.

Have you actually used GraphQL in production or for a wide-scale project? A lot of these criticisms for GraphQL comes from people who have played with it for an hour and determined it's not good. Give it a real chance and you'll see why big companies are using it and understand why the ecosystem is growing so fast.


Yes. Used it for a a couple of large projects at BigCo. Was actually brought in to "polish" a few things. One of the original team members thought it was cool. It was a disaster. Uncovered issue after issue. Convinced management to run a bug bounty program through hackerone and I'm going to let you guess what happened.

If you're so brave and confident find a good pen tester and let them have a go at your api. It's a humbling experience.



I hate integrating with public GraphQL APIs as well. Give me a REST API pls for the love of god. It makes me sad GitHub's new projects API is GraphQL-Only.


Netflix is large company with huge IT/software workforce. And as I have seem in large companies tech managers and engineers don't usually keep waiting for actual problem to appear and develop solution for it. They are going to take initiative to migrate legacy monolith to next generation micro services, GraphQL architecture and in process save their jobs.


The timing of this is hilarious. Here is something that's on the front page at the same time: https://news.ycombinator.com/item?id=36380711


Thanks. Great read.

When work or personal issues overwhelm me I go with this kind of meta analysis and stop usually at Keynes quote : In the long run we are all dead. This helps me get though the day.


Have you tried the alternatives? We went with Odata, and it's hell. It's fine on the client side, but it's terrible to work with on the server-side. We went down the C# path because everyone else is either using RPC or GraphQL, but even Microsofts own libaries don't work together. The model creatirs for Odata and Entity Framework sort of work the same, but are also different enough to cause some real annoyances and once you add asp.versioning it becomes even worse. We went with Odata because we had a hefty client that consumed Odata through a client library that we build ourselves, and at the time it seemed like it would be fine. A year later it turns out that it would've been better for us to rewrite everything to work with GraphQL, and, we may actually end up doing that eventually because the Odata .NET support is so terrible that we're constantly having to rewrite parts of it to get it do things that are trivial in GraphQL.

You can of course go other routes, we took a serius look at tRPC, but it seemed like it would end up being a lot of work. Actually quite similar to how doing the things you want from a frontend perspective is a lot of work if your backend is "just" rest.

> Last, I don't understand what Netflix does that is so complex that would warrant something like gql. I just don't.

If you dig into the other blog points that the OP link to you can see that it's because they needed better performance, more security and better control of the flow. I think you may underestimate how much you get for "free" when using graphQL. It has so much adoption, that there are so many tools that you won't have to build from scracth, even if you're Netflix. You can see our Odata library as an example of this, there are client libraries that we could've used, but they're bad. So we had to build our own. With GraphQL we wouldn't need to do that.


IMHO, Rest works just fine. If you are serious about performance I don't really get how you do that with GQL. maybe I'm just ignorant but the apps I've worked on were medium to large size and it was a fricking nightmare (apollo-based, a couple of years back).

Here:

https://hackerone.com/hacktivity?querystring=graphql&filter=...


> maybe I'm just ignorant

Never that, but maybe inexperienced? Nothing you say is wrong, but you need to look at it from the organizational point of view. The way we build (most, all of them where I work, but I'm sure people can point to places) "enterprise" apps today, is that we have a frontend that's build in Typescript, and then something behind it to move the data.

Your frontend engineers are going to want a query language that allows them to pick and chose the data they need. You can do that with rest, but you really, really, don't want to build it yourself. Some frameworks have options for parts of it, but in general you're out of luck when it comes to things like inheritance trees on objects. So you have Odata, RPC, GraphQL, and while Odata is nice on the client side, it's not nice on the server side. RPC's work great, but they are also a lot of work, and then you have GraphQL. What GraphQL allows you to do is the combination of having an engine that makes your frontend engineers happy, while allowing your backend engineers a lot of visibility on resource drains. This means that you can work on the heavy load areas, and "leave" the others, more easily than you can with Rest where you're likely going to "over engineer" a lot of your backend. RPC is sort of like Rest in that department, but because it's intended to be like that, its rarely an issue because you chose it for that reason.

Or to put it more simply. You use Odata and GraphQL and not Rest because they lessen the "working together" burden.


I think it's simple. You can get the best performance with REST, but you have to really put lots of resources into it.

On the other hand, with constraint resources, you likely end up with better performance when using graphql because of the reduction of requests and decreased latency.

In most cases, graphql hits the sweet spot.


> reduction of requests and decreased latency.

How?

GQL still depends on an API or a database, isn’t it? And depending on where that Api or DB is located in relation to the calling user/app latency is still going to be the same? What am I missing here?

If you are implying that GQL somehow intelligently caches data, then all the issues with cache invalidation etc still would apply, correct?

The problem with some of these debates about GQL vs Rest us that you have people either saying GQL is great or bad and same with REST. I wish there is someone that breaks it down and truly explains the pros and cons of each.


You are right, but you are missing the frontend part.

e.g. frontend says "backend, give me the users". Then later, for every user it says "backend, given me the users favourite images". However, with graphql the frontend can say "backend, give me the users and include each favourites images".

Even if the way to retrieve it from the database is the same for the backend, there is still reduced latency because it is only

frontend->backend->db (users)->backend->db (images)->backend->frontend

instead of

frontend->backend->db (users)->backend->frontend->backend->db (images)->backend->frontend


I think that it might be because the difference is mostly in how we work together. With GQL your frontend and backend engineers are always happy, with Rest they are always at each others throats to deliver. This is because GQL gives your teams the tools they want. On the frontend you get the data access without ever having to talk with your backend, on the backend you get the load data without ever having to talk with your frontend. So both your frontend and your backend can focus on what they do best without ever talking with eachother.

Obviously that's not exactly how it works, but if you give your frontend engineers the full query abilities of GQL and your backend the ability to monitor and then fix bottlenecks through the GQL load tools you simply remove a lot of the conflict zones in modern development.

You can do everything you can with GQL with Rest, but you're not going to want to do it. And speaking from experience, you're not going to want to do it with Odata either unless Microsoft magically improves the experience after 10 years of it sucking.


GraphQL is such complete and utter garbage for anything but the simplest of queries. I pity anyone who has to use it for anything more complicated.


i would not go as far as saying complete and utter garbage, but it 95% of cases it brings with it a can of worms that you don't need and don't want. All in the name of "frontend developer velocity"!


This rhetoric pops up every time gql is discussed on HN, and it is invariably full of misconceptions and, well, nonsense, that just tells anyone who's actually used gql that you clearly haven't.

I never understood why people insist on having strong opinions on things they clearly know nothing about.


For us the primary value is behind the customizability of it all. One of our main requirements is to give user A LOT of flexibility to customize the default frontend to suit their needs.

On top of that we are running DDD in the backend with ARs being spread over multiple different services.

We did experiment with rest early on, but we found out that we would need to make our frontned to be extremely complicated and vocal to handle the customization/data fetching requirements or build our own REST gateway on top of open API, doing, essentially, the same thing that graphql gateway does out of the box.

Adopting graphql was scary at first with low team exposure to the technology, but using REST would have made our life much much harder


My main issue with it is client-side caching doesn't map cleanly to graphql. I want well-defined objects to cache.


that's solved with Relay's graphstore


There's a solution to everything /s We started with a somewhat simple problem and now let's keep throwing things in. How about something I can just curl? Is that too much to ask?


Well, no, Relay is how GraphQL is meant to be used and is Facebook's client implementation and quite opinionated. Apollo and others came around to be less opinionated (and thus allowed people to re-use their old REST style designs) in GraphQL.

You can in fact just curl a GraphQL API. In simple projects where I don't need caching I just use the REST library and make a simple HTTP request with a graphql query string. I get back a JSON object to consume.


GraphQL is like SQL. It’s an extremely leaky abstraction but in the hands of someone experienced, you can do amazing things with a fraction of the effort required.

But just like SQL, you have people who happened to learn SQL in passing and it’s like a table saw in the hands of someone who doesn’t know what to do.


Kong seems to have some offerings on the API gateway security front for GraphQL https://konghq.com/blog/engineering/graphql-authorization-at... I haven't looked at it very closely yet, but I'm wondering Kong for other reasons (unrelated to GQL)


GraphQL really shines when it comes to providing a unified data layer for frontend teams. Having a consistent, typed API is a big time saver for developers building data rich applications. The ability for frontend teams to shape the data they need without talking to a backend developer and reduce the number of requests made to the API makes for a perfect match when building high performance applications.


> Also, in general being able to say "i want to do whatever" and request everything at once is an anti-pattern IMHO, especially after HTTP2 became mainstream and doing multiple requests is reasonably fast.

It's not about performance, it's about being able to trivially get the data you need in one request and get it back in a way that you've structured.


People are drawn like moths to a flame to anything that is poorly specified and are repelled by the well-defined. A visit to the ontologist is feared somewhere between a visit to the oncologist and the orthodontist.

To be fair, GraphQL has a real specification now but it didn’t back when it was taking off like wildfire.


The state of the art of GraphQL tooling around securing and versioning has evolved significantly. You may want to take another look at what’s out there.


I was just researching graphql versioning and the recommendation is not to version because the graph is supposed to be an evolving entity.


mutation createUser-v2

Seen that in some productive APIs, always fun.


[flagged]


Put this into the "my code is self-documenting" bin.


my self-documenting code is evolving!


Could you please provide some pointers?


How does http2 skip the speed of light to speed up sequential requests?

Isn't the back and forth across the network the big problem?


In the beforefore time, you would need to establish a connection for every request you did if you wanted to make multiple requests in parallel and you were limited by how many request yoi could have in flight in parallel. With http2 you can mux the requests together through the same pipe. Yes, if you need to retrieve A to figure out you need B, it's not going to be "faster" but you would do the same thing on the server side.

Also, for a well architected backend you can spread load better on the backend and shockingly you can also leverage caching if you are doing a "dumb" rest api.


GraphQL makes it straightforward to do conditional queries like:

  … on Book {
    title
    author
    if_viewer_can_purchase {
      price
      shipping
    }
  }
This is quite annoying to do with traditional REST without overfetching data you don’t need.


I feel like this is a bad take: I’m not sure what your experience with graphql is but your comments about Netflix strike me as naive. I think there is a simplified version of Netflix that doesn’t do eg recommendation or history or different contracts in different countries and so on, which is maybe just a few api calls, but I don’t think that’s what Netflix is. And are they actually reinventing the wheel here? I thought graphql was a Facebook thing. Maybe you meant to say that they are rewriting systems pointlessly but it (also) feels like a bit of a generic criticism that is easy to apply to companies for which in-house systems make sense.

(Edit: it’s not even like this is a graphql vs rest change as Netflix have had graphql for years and they have a custom api system that seems a lot more like graphql than it does rest)

I’m curious what you think the best advantages of graphql are, particularly for a larger company like Netflix?

I would guess:

- reduces coordination/contention between different frontend/backend teams (eg there are many clients – desktop, mobile, various smart devices – but maybe other front ends too like something customer support might use).

- cuts down on ‘boilerplate’ api work. For example, maybe you have some property X of each item Y in your catalog, but which you don’t get on the request for the catalog, and that you want to display this now (maybe it’s some new experimental feature you need to thread through from some database table to the front end). You need to choose between adding X to the catalog (potential version woes…) or managing a bunch of requests for X for each Y (risks being slow or bad in a few ways), or add some non-restful api endpoint that takes a list of Ys and gives you their X properties. With graphql you need to teach the backend how to get X of Y but the frontend only needs to change the query.

- it potentially lets you apply access controls in a more straightforward way. If someone is from the US, maybe there are some shows they can’t see. In that case we probably want to hide all records in results about shows they can’t see. (Alternative example: various properties of other people’s accounts). If you have many separate api endpoints, it feels easier to me to accidentally screw up on one of them.

I’m not really very familiar with graphql but the middle option is the most compelling one for some of the things I work on (which are nothing like Netflix). One assumes that some people from Netflix had reasons for graphql and I’m interested in what they were rather than some imagined Venn diagram with the current api in the ‘not invented here’ area and graphql in the intersection of ‘invented here’ and ‘not yet a thing we have’. I’d also be curious to see how well it works out for them over time – perhaps they’ll regret it but maybe not for the reasons you oppose graphql; if there are organisational problems (like some team becoming a big new bottleneck or some teams being unhappy about it being ‘forced on them’), they can be hard to write about.


The comment about Netflix was suppposed to be a hyperbole.

I would be curious how Netflix itself justifies this except for: we wanted to do this cool thing, so why the fuck not


Netflix might be a good example of where GraphQL is good: There's not one frontend, and one working app, but many, just by hardware platforms they support. Add to that changes in behavior for different regulators, licensing agreements and such, and I bet there's a bunch of bespoke little frontend things that need slightly different information from each other. In that environment, queries aren't really completely free flow, which is what could ge you in trouble, but it might be nice to provide cheap customization of the API, instead of building bespoke backend tweaks for every one of those bespoke frontends.

It's ultimately not unlike how people wonder why the Uber app is so big, when everything seems so simple to them: Each interaction appears simple, but put all the interactions from every person together, and the problem is far harder than it seems.


It's 2023. There are _so many tools and patterns now_.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: