Hacker News new | ask | show | jobs
by jbjorge 3235 days ago
To all considering using graphql, let me tell you something that was unclear to me when I first tried it: If you plan to use it with a schemaless (nosql/graph) backend, graphql will force you to write a schema for it. If you can't (due to dynamic data), you will just end up forcing graphql treat your data as json-blobs with no schema. Graphql turns into a json-blob transmitter with no benefits. Also, if you have deeply nested/recursive data structures, the client performing the query needs to know just how deep it should query. This can lead to ridiculous queries if you're running on a graph db where the client doesn't know how many vertices it should traverse. REST is a better fit if the above is true for you.
4 comments

To anyone put off by this comment: don't be. With all due respect the parent commenter has misunderstood how to shape their API responses.

GraphQL excels at nested data structures. When you have infinitely recursive child nodes of the same type (like ancestors in a family tree) the GraphQL list type should be used.

To help solve the nested/recursive query problem, Facebook created dataloader: https://github.com/facebook/dataloader There's graphql integration info on the blog: http://graphql.org/blog/rest-api-graphql-wrapper/#taming-pat...
I probably was a bit unclear. Lets say I've got a family tree stored in a db that goes back 1000 years.

Through graphql I want to find my first ancestor following all mothers backwards. The query would be:

  query familyTree {
    name,
    mother {
      name,
      mother {
        ..and so on for an unknown number of nestings
      }
    }
  }
Dataloader solves batching of the nested query on the server, but doesn't solve the problem of not knowing what the correct number of nestings the query should have.

Of course it's possible to create a new graphql endpoint for this type of query, but then we've just recreated REST in graphql.

Hmm, you're not quite thinking in GraphQL properly. That isn't how your schema should be designed.

Your mother field should resolve to a Person type, with a mother and/or ancestors field, which would be a graphql list type of the Person type.

Something like this:

  Person {
    mother: Person
    femaleAncestors: [Person]
  }
Yeah ideally ancestors would be a `connection`/`edge` with filters:

``` Person { ancestors(gender: Female, orderby: [AGE], first: 10) { node { name } } } ```

Absolutely. Personally I haven't made much use of NoSQL, I'm sure there are plenty of use cases, but for ancestry I would still use a relational db.

I do see how nested objects might look like a perfect fit for this, since families are literally "nested objects". Perhaps there are plenty of advantages to using NoSQL and shaping the data this way... but the thought of creating an API With that structure is terrifying to me, haha.

Question to OP: are you using this structure for a live api/website I can take a look at? Does each node have an absolute ID? Do you normalize your data? Maybe I'm thinking too much in relational terms here? I'm genuinely curious about this.

For the recursive issue we have a directive that lets us specify a recurse level. The server validates that with a maximum value.

As for schema-less we generate a scheme that includes all types and fields but we filter out any non-available ones (according to user with) each time an introspection query is issued.

I believe that Falcor's JSON Graph[1] supports recursion rather well.

[1]: https://netflix.github.io/falcor/documentation/jsongraph.htm...