9 ms·
What I've not understood about GraphQL is how to map it to My/Postgre/etc SQL. The info about resolving specific fields seems .. complex, and difficult to optim
by notheguyouthink 9y ago
What I've not understood about GraphQL is how to map it to My/Postgre/etc SQL. The info about resolving specific fields seems .. complex, and difficult to optimize tom say, reduce SQL calls.
Is there a library that, say for Golang, helps translate a GraphQL Query into SQL statements to actually get the data?
- bdibs 9y agoI haven't played with the Golang server yet, but with Node you just set the resolve to something like: resolve (root, args) { return Db.models.post.findAll({ where: args }); } (sorry for the lack of markup, I don't know how to do anything here yet) Here's a blog post specifically for Golang: http://alexandrutopliceanu.ro/post/graphql-with-go-and-postgresql/ http://alexandrutopliceanu.ro/post/graphql-with-go-and-postg...
- ruslan_talpa 9y agohttps://subzero.cloud https://subzero.cloud (1 query, optimal for any number of levels) https://github.com/stems/join-monster https://github.com/stems/join-monster (1 query, overhead for more than 2 levels) https://github.com/facebook/dataloader https://github.com/facebook/dataloader (best case, 1 query per level, in sequence )
- dobs 9y agoYou might be interested in postgraphql: https://github.com/postgraphql/postgraphql https://github.com/postgraphql/postgraphql Otherwise it depends on your GraphQL implementation and what DB adapters or ORMs they support. For example, `graphql-ruby` includes a generator for a Rails-compatible GraphQL schema.
- enjoylife 9y agoIn a side project of mine, I leverage https://github.com/neelance/graphql-go https://github.com/neelance/graphql-go, which is one such implementation written in Go. It might appear verbose at first, with it needing exported method names all over the place, but I've grown accustomed to it now. The repo has a full star wars example which helped me to get oriented quickly.
- xtagon 9y agoI'm interested in learning solutions for this as well, but it's hard to find because most GraphQL tutorials stop at the resolver level. There are a couple approaches I've seen for mapping to an SQL backend. One is batching - You get the top level resources, then save their accosted record IDs until later so you can make fewer calls to get their associations. This still makes quite a few database calls, especially for deeper queries or many different type of objects. Another approach is "whole tree up-front" where you take the AST of the graph you're trying to resolve, and convert that to one big SQL query that joins all the associated objects. This can be more performant in some situations as it only makes a single database query, but a drawback is that larger queries eat up a more bandwidth from your query since having many joins causes data duplication. Another drawback is that having a single query makes it so you can't cache each resolver individually like you might be able to do with a batching solution. I don't have all my links handy but here's one you can check out: https://github.com/facebook/dataloader https://github.com/facebook/dataloader If anyone has something to add please chime in! I'd love to hear how people are really using GraphQL with SQL backends!
- benwilson-512 9y agoHey! I'm one of the co-authors of the Elixir implementation Absinthe. Absinthe has an extensible middleware mechanism from which you can build a variety of different batching patterns. We run our API at http://www.cargosense.com/ http://www.cargosense.com/ entirely via GraphQL over quite a lot of postgres tables and this has remained very performant for us. Elixir makes it easy to do concurrent batched requests, as well as in memory caches that live for either the duration of the request or long as desired. For some particularly complicated cases we have a materialized view, but this is largely used to power a reporting service that builds snapshots from this. Any questions you have in particular?
- raarts 9y agoI've read comments here on HN that the server side of graphQL is notorious hard to implement, the resolvers end up being really complicated or slow. Anyone care to comment from practical experience?
- andrewingram 9y ago2 years of experience, it's easy. As long as you resist the temptation to build clever abstractions too soon, there's nothing hard about it.
- strken 9y agoI've implemented three graphql backends - one wrapping a rest api, one wrapping mongo, and one wrapping postgres. The key, just like in rest, is to keep the different layers isolated. If your resolvers never do anything more complicated than parsing arguments and passing them to the next layer, it's hard to make them complicated. One project parses the graphql ast and there's a small performance gain from that, and another batches identical requests with Facebook's DataLoader library, but those are done behind the scenes and don't end up polluting the resolvers, and to be honest they probably weren't necessary. Most of the resolvers end up looking something like { type: FooType, args: { fooId: GraphQLString, ...paginate.args, }, resolver: createRESTResolver( ({ fooId }) => [`${services.foo}/:fooId`, { fooId }] ).use(paginate), } but if I was doing it again I'd probably abstract the creation of the entire field rather than just the resolver.