News for hackers. Stuff that matters.
Re:GraphQL Performance Monitoring Is Hard by davnicwil on Saturday July 27, 2019 @05:17AM (#20541155)
To me, the question is the other way round because the advantages (pointed out by all the other comments in this thread so I won't repeat) are clear, kind of immediately.

It's the disadvantages, particularly the 'unknown unknowns' that I wonder about, and that's what's kept me from using it. GraphQL so far seems like the archetypal counter example for the 'use boring stuff' philosophy of software engineering. I kind of hope I'm wrong here, because the advantages are big and pretty cool.

Re:GraphQL Performance Monitoring Is Hard by strken on Saturday July 27, 2019 @06:04AM (#20541270)
GraphQL is pretty boring, at least on the server. You give your GraphQL library a schema and tell it how to deal with fields, and then it makes a tree of fields from your query and populates them according to your instructions.

It can get "exciting" on the client, particularly with libraries like Apollo. See for example the bug https://github.com/apollographql/apollo-client/issues/1186, which took two years to fix. The tooling for persisted queries can also be hard to set up, and they're close to required if you want to expose GraphQL to your client.

Re:GraphQL Performance Monitoring Is Hard by dmitriid on Saturday July 27, 2019 @06:43AM (#20541371)
It’s actually exciting on the server. Ad-hoc queries with unlimited complexity? Check. No caching? Check. No auth? Check.
Re:GraphQL Performance Monitoring Is Hard by strken on Saturday July 27, 2019 @07:58AM (#20541600)
The solution to ad-hoc queries is to not use ad-hoc queries. Persisted queries are becoming common.

Caching is no harder in GraphQL than it is anywhere else. You define resolvers; if you want to put stuff in Redis, you're free to do so.

Auth is also no harder in GraphQL than it is anywhere else. You have complete control over what happens in a resolver, which includes authorising access and throwing an error/returning null/etc.

Re:GraphQL Performance Monitoring Is Hard by davnicwil on Saturday July 27, 2019 @08:09AM (#20541643)
To dig in on the persisted queries thing, which I mentioned in a reply to the sibling comment, have you seen practical advantages doing this vs just doing a plain old RPC style http API?

It seems to just move all the flexibility of GraphQL to dev time, and makes it only useful for a private API where you control both the client and the server. This is all fine, but then I just don't see why you'd move away from a classic API where caching is free for GETs and you don't have to go through the abstraction of GraphQL schemas and resolvers etc to do your endpoint logic, you can just do it.

One thing I could possibly see is that client side libraries like Apollo etc bring huge advantages like free client caching or other things I'm not aware of - is that the case?

Re:GraphQL Performance Monitoring Is Hard by strken on Saturday July 27, 2019 @08:30AM (#20541722)
At the company which used GraphQL in production, two of the major reasons for adoption were decoupling the backend from the UI of the client, and allowing front-end developers to easily update the payload without making changes to the server, which weren't affected by using persisted queries. Caching was handled by separate backend services rather than the graphql service or the client, which wouldn't make sense for every usecase.

Apollo was really useful for managing state across the client. Tools like optimistic updates were very nice too. Unfortunately, it was somewhat buggy when we were using it, and the API kept changing, but I think it's more stable now.

It was also good to have a well-defined schema between client and backend, although you should have one anyway.

Re:GraphQL Performance Monitoring Is Hard by davnicwil on Saturday July 27, 2019 @09:01AM (#20541844)
Yeah, that makes sense. I think the usecase I'm optimising for is solo and/or full stack engineers in a relatively small team where everyone is free to do everything. When that's the case, obviously these kinds of abstractions may just get in the way rather than help.

I've worked for companies in the past that had the organisational setup you describe, however, where frontend engineers didn't even have pull access to the code for api services they were talking to, where this would have been a massive advantage in terms of productivity.

I seem to end up at this conclusion in most discussions about GraphQL, usually with facebook scale being referenced, where it seems that as a technology its main advantages might actually be architectural in terms of the organisation of how massive systems are engineered, by huge numbers of people.

The temptation is always to jump in and compare the technical merits and specifics, and overlook this, but I'm coming more to the opinion that this is the answer here to when to use GraphQL over REST / RPC over http. That is, at the scale of a massive engineering organisation, it might be an abstraction whose advantages outweigh the downsides, but probably not if you're a small team.

Re:GraphQL Performance Monitoring Is Hard by strken on Saturday July 27, 2019 @04:50PM (#20544113)
It's less about what front-end engineers are allowed to do, and more about having an abstraction flexible enough that new front-end features don't need changes on the backend unless the data model changes. Backend or full stack engineers can design endpoints however they want, whether it's RESTful JSON or gRPC, and GraphQL acts as a flexible aggregation and presentation layer.

If you're finding that your endpoints are filled with unnecessary optional fields, that they're specific to a single screen in the UI, that nearly every new feature involves work that's duplicated across front-end and backend, or that you're suffering a performance hit from the round-trip time between front-end and backend when you query nested objects, then GraphQL can be an option. These are problems that you run into when your product starts to get bigger and more unwieldy, so if your UI has five screens and doesn't reuse the same content then you might not see a lot of gain. Having said that, my former company was under ten engineers, so I don't think you need to be Facebook-scale to benefit.

Totally agree that the advantage is architectural. It's not a question of technical merits or of REST being bad. GraphQL is a layer of abstraction to separate data from presentation, and like other abstractions, you shouldn't use it unless you have a reason to.

Re:GraphQL Performance Monitoring Is Hard by dmitriid on Sunday July 28, 2019 @12:21PM (#20548290)
Edit: my viewpoint is applicable to public APIs. If your client(s) and your backend are under your control, then GraphQL is useful.

> The solution to ad-hoc queries is to not use ad-hoc queries. Persisted queries are becoming common.

So, you either reinvent REST, or fall prey to ad-hoc queries with potentially unlimited complexity.

Also, persistent queries don't save you from unlimited complexity when those are automatically persisted, which is what Apollo offers.

> Caching is no harder in GraphQL than it is anywhere else. You define resolvers; if you want to put stuff in Redis, you're free to do so.

Putting stuff in Redis does not make it caching.

> You have complete control over what happens in a resolver, which includes authorising access and throwing an error/returning null/etc.

So, you throw an error in a deeply nested resolver in an ad-hoc query with unknown complexity, and .... this is "no harder"?

Re:GraphQL Performance Monitoring Is Hard by barbellguy97 on Saturday July 27, 2019 @07:41AM (#20541541)
What do you mean wirh unlimited complexity, no caching oe aithorization? Have you ever used ot server-sody? Because they are all solved problems, except maybe caching in the transport layer, depensing on which forn of caching you're targetting.
Re:GraphQL Performance Monitoring Is Hard by davnicwil on Saturday July 27, 2019 @07:48AM (#20541565)
What are the generally accepted solutions to these problems? Can you point to any sources? They're probably the big 3 that have stopped me from using GraphQL so far.

Only thing I'm currently aware of that might 'solve' arbitrary complexity and caching is limiting queries to pre-approved whitelisted ones the server knows about and references with an id, which is more of a workaround than a solution, and removes the main advantages for whole sets of usecases like open apis for 3rd party use.

Re:GraphQL Performance Monitoring Is Hard by Ralfp on Saturday July 27, 2019 @10:49AM (#20542265)
Unlimited query complexity:

- graphql() function takes "validators" argument for a reason ;) There are multiple strategies for limiting complexity, but common ones are boxing (limiting depth and width of query) or query cost limitation.

For auth, you authenticate user using custom middleware before entering the query executor. Inside query executor you can do one of many things, depending on what makes sense for you: error field resolution, return "null", or return custom type like "ObjectNotFoundError".

For caching, you cache inside resolvers that do something costful, or in data loaders those resolvers call.

Re:GraphQL Performance Monitoring Is Hard by davnicwil on Saturday July 27, 2019 @11:08AM (#20542348)
Thanks for this reply!

Are things like query depth, width and cost limiting available as parameters to common libraries?

On the auth thing, one thing I commonly do with REST is have a general 'is this user authenticated' middleware and then later have a 'permissions' middleware that checks if the user has rights to see/modify the thing they are trying to, but that's at the service level for that particular thing.

Would you follow a similar strategy in GraphQL? Generic auth in a middleware for a user, then specific access management auth inside specific resolvers later on?

Re:GraphQL Performance Monitoring Is Hard by Ralfp on Saturday July 27, 2019 @01:54PM (#20543177)
> Are things like query depth, width and cost limiting available as parameters to common libraries?

No, they are mostly 3rd party utils. I those exist for Apollo server.

> Would you follow a similar strategy in GraphQL? Generic auth in a middleware for a user, then specific access management auth inside specific resolvers later on?

Yes. Or I would move auth check up a level, and implement schema directive like "@authenticated" or "@hasPerm("perm")" so resolver would do only data resolution, but each approach has advantages and downsides.

Re:GraphQL Performance Monitoring Is Hard by dmitriid on Saturday July 27, 2019 @07:48AM (#20541560)
> What do you mean wirh unlimited complexity, no caching oe aithorization?

I mean what I mean exactly.

- GraphQL allows ad-hoc queries of unlimited complexity.

- Since it's POST requests, there's no caching on the HTTP layer.

- Since it's add-hoc queries, it's hard to devise a cache for the DB layer.

- There are no easy solutions for either authentication or authorisation for queries (and subqueries and/or fields)

> Because they are all solved problems

If by solved you mean "busily reinventing the wheel and adding layers and layers of unneeded complexity, and it will only work if you buy into a single vendor's solution such as Apollo".

For crying out loud, one of the "solutions" for caching is to actually parse both the incoming and the outgoing requests, read the fields and decide if it needs to be cached.

Re:GraphQL Performance Monitoring Is Hard by Aeolun on Saturday July 27, 2019 @08:10AM (#20541649)
> For crying out loud, one of the "solutions" for caching is to actually parse both the incoming and the outgoing requests, read the fields and decide if it needs to be cached.

That sounds exactly the same as the thing you do when caching a HTTP request to me..?

Whether the fields are in the request body or the query string is pretty much irrelevant.

I think you are just annoyed that they misappropriated HTTP to do it.

Re:GraphQL Performance Monitoring Is Hard by dmitriid on Sunday July 28, 2019 @12:17PM (#20548261)
> That sounds exactly the same as the thing you do when caching a HTTP request to me..?

ETag, Is-Modified-Since, Last-Modified, Cache-Control don't require any parsing of the request body.

And the relevance is huge. It's one thing to match a resource id in a URL in an idempotent cacheable request. It's another to have request body fully parsed by a caching middleware layer in a non-idempotent non-cacheable request.

> I think you are just annoyed that they misappropriated HTTP to do it.

They looked at HTTP and threw out everything HTTP already has built in. And all the tools.

Re:GraphQL Performance Monitoring Is Hard by Aeolun on Sunday July 28, 2019 @07:09PM (#20550323)
> It's another to have request body fully parsed by a caching middleware layer in a non-idempotent non-cacheable request.

As far as I understand it you can use the request body directly as a caching key. No need to parse it. If you request exactly the same thing there’s no need to re-request it.

Re:GraphQL Performance Monitoring Is Hard by dmitriid on Monday July 29, 2019 @02:16AM (#20551911)
That would be a way to do it, but that would require the client to send exact queries. Depending on how queries are constructed, that will not always be the case.

Also, a quick look at the top search query for “Apollo graphql caching” shows that Apollo needs to deconsteuct the object (both for the request and the response) to be able to cache things: https://www.apollographql.com/docs/react/advanced/caching/

(I’m using Apollo here as one of the most advanced GraphQL solutions)