5 ms·
Sure, but you're asking your server to support a full query language. Even with data-fetch on a js-impl (or ... a hell of a lot of by-hand tooling in Python wit
by KirinDave 9y ago
Sure, but you're asking your server to support a full query language. Even with data-fetch on a js-impl (or ... a hell of a lot of by-hand tooling in Python with Graphene), this overhead really hurts your qps.
To be honest, I sort of wonder if the right place to implement the GQL interpretation and scheduling layer is in a service-worker.
That way, the client devs who love this complex query language can also support the queries they need and ensure their calling conventions don't violate performance boundaries in the gql server implementation.
- NightMKoder 9y agoFacebook’s Relay solves the throughput problem by effectively precompiling queries. Their production apps only make a subset of the requests of the full graphql language - and those are frozen at deploy/compile time. In some sense this makes their production graphql more like “auto-generated REST” from the server’s perspective. That said, thinking of this in terms of client vs server devs isn’t useful - it’s not like anyone on the team want to see the servers burn. The beauty of graphql is it’s descriptiveness - you could create a query performance score and fail CI if your main page queries are hitting too high of a cost. A meet up in SF last year had some FB engineers discussing this - they do something along these lines before shipping their android/iOS apps.
- KirinDave 9y ago> Facebook’s Relay solves the throughput problem by effectively precompiling queries. Their production apps only make a subset of the requests of the full graphql language I am aware of this, and it seems ridiculous to me. It discards the value of having a graph query language. I'm open to being wrong about this assessment. Why am I using a new query language if it's going to end up being exactly the same as the old rest query environment? > That said, thinking of this in terms of client vs server devs isn’t useful Considering it from a typical labor division standpoint or by technical dependency and requirements isn't useful? I disagree. > The beauty of graphql is it’s descriptiveness Which you have said the "performant" way to handle is to discard and turn into a formulaic series of bytes that is indistinguishable form a new term encoding on restful POST bodies. > you could create a query performance score and fail CI if your main page queries are hitting too high of a cost. This is exactly how everyone already tools RESTful endpoints. Whole industries are built around scoring endpoints this way. Inevitably my concern about GraphQL being hard to implement server side is inevitably met with Facebook's outer and inner solution. The outer solution: Just pretend it's graphql, really it's postbodies and we won't let you write custom queries except for column filtering (which these solutions WILL fetch). The inner solution, it has been intimated to me, is they have custom GQL libraries written in Haskell using Haxl that they don't share because the industry is too busy being afraid of it. Sadly, these don't appear to be open source (and even if they were, a lot of shops would not be equipped to use them).
- riffraff 9y ago> Why am I using a new query language if it's going to end up being exactly the same as the old rest query environment? the client controls the APIs without you touching them. It is required that the client syncs up with the server but you don't have to touch backend code to change the set of fields you want (this works for internal clients, not open APIs, clearly). If you're thinking "but I can just allow the client to select fields in my JSONAPI compliant endpoint", yes, you can, and when you add includes for nested fields, and nested selections, you basically get 90% of graphql :)
- KirinDave 9y ago> yes, you can, and when you add includes for nested fields, and nested selections, you basically get 90% of graphql :) True, but until someone provides a great software kit for doing that work, I'm not going to allow arbitrary extensions.
- andrewingram 9y agoIt's really not that hard to build a relatively optimal GraphQL server. Obviously it requires paying careful attention to performance, and to take steps to mitigate abuse (query whitelists, complexity caps etc). If you were to move the implementation off the server and into the client you'd use a lot of the benefits of GraphQL in the first place (performance being a major one).
- rhizome 9y agoObviously it requires paying careful attention to performance, and to take steps to mitigate abuse (query whitelists, complexity caps etc) Are these also "not that hard?"
- arianon 9y ago"Query whitelists" sounds like sending to the server something like `{"query_id": 4, "variables": ...}` instead of `{"query": ..., "variables": ...}` which are straightforward to implement using any kind of server side key-value store and a middleware that maps the `query_id` back to the corresponding `query`, a tool that can help you with this is Apollo's PersistGraphQL [1] I have no idea how I would go about implementing complexity caps though, but I guess I would do something like what GitHub has done for their own GraphQL API [2], which they explain better than I can. [1]: https://github.com/apollographql/persistgraphql https://github.com/apollographql/persistgraphql [2]: https://developer.github.com/v4/guides/resource-limitations/ https://developer.github.com/v4/guides/resource-limitations/
- exogen 9y agoAnother simple option for limiting complexity (I've considered implementing this in my GraphBrainz project): in the `context` provided to the GraphQL query resolver, increment a counter whenever a resolver requires fetching from an external API/database/etc. (whatever "too much of" would constitute abuse or just take a long time). Fail if the counter reaches some threshold. This would be really easy. Also, instead of multiplying node counts like GitHub does (which is pretty clever!), another simple option would be to look at the depth of the query (how many levels down is the deepest leaf), and fail if it's over some maximum. This is also very easy to do as you get the query AST in the `info` field of the resolver. (This one is less effective than the one above since depth doesn't totally match up with resource usage, fields can be aliased, etc. but you get the idea.)