Reason React Apollo

reasonreact

#1

Hey everyone! I open-sourced some code I’ve been writing over the last several months in support of the app I’m building at work: reason-react-apollo!

It’s bindings + codegen for working with Apollo’s react-hooks library, and it takes an alternative approach to typing your GraphQL stuff than graphql_ppx. Specifically, it uses abstract types for each of your schema types that can be shared around your project instead of a specific type for each operation you define. I’ve never liked that tradeoff that graphql_ppx required, so I gradually developed an alternative approach! And, with Apollo’s release of the hooks API, everything came together really nicely.

If you’re interested in trying it out the docs site explains how to get started (it’s using GraphQL Code Generator for the codegen, so the setup mostly involves getting that configured). I’ve love to hear any feedback about how it works with your schema, the docs, or really anything! I’ve really enjoyed the experience of writing components that use queries/mutations this way and hope others will benefit, too!


#2

Nice work!


#3

Cool project! I’m happy with graphql_ppx, but looks like this project makes different tradeoffs and opinionated choices compared to what’s already available. It is worth a look when existing solutions don’t fit the bill:

  • Apollo over Urql, Relay etc.
  • External tool (graphql-codegen) over a PPX
  • Future over Js.Promise or Repromise

Thanks for making GraphQL in Reason more approachable for people with different workflows that are not covered by the existing tools.

I have one concern, if I’m understanding this correctly (please correct me if I’m wrong):

  • graphql_ppx by default uses objects which are structurally typed, with the usual tradeoffs such as syntactic cost and error messages

  • graphql_ppx can optionally use user-defined records via @bsRecord directive, but this will result in some boilerplate and incompatible record types between different queries that fetch different fields

  • This project instead opts for generating one abstract type & getter functions for its fields per each GraphQL type in the schema, and not the actual query being performed. These types are then used across different queries with some runtime checks. This results in loss of type safety and errors (exceptions?) when you try to access a field you didn’t fetch in your query.

In my opinion this is not a great tradeoff to make. This approach gives up major advantages of Reason’s type system, and also is more error prone (say, compared to doing this with REST) since with GraphQL common pattern is only retrieving fields you need.


#4

Hey @osener thanks so much! You’re right on in the trade-offs you’re listing. And, I agree, in some ways it definitely feels like step away from all the benefits of writing in a strongly-typed language to begin with.

Here’s how I justify it (at least to myself :laughing:) - though you introduce the possibility of an error your type system won’t catch (that is, under-fetching in a query), you’re almost 100% certain to encounter this during normal development. In most cases, as soon as you try to do something with the query - it’ll be clear the data is not there! Combined with a really easy to diagnose error message (the type accessors tell you exactly what field you were trying to access on which type), it’s incredibly easy to diagnose and fix. The chances of shipping an error of this type to a user is slim to none.

And, for the cost of this tradeoff, you’re able to use the same named types as your actual schema, so when you see the types in your frontend code, it’s really easy to tell what’s going on. In a moderately complex app, this can be a real benefit, especially if you have new people contributing, or even pieces you need to go back and touch months later when you’ve forgotten what’s going on.

All that said, I fully understand that tradeoff doesn’t make sense for all users, or all apps. Like you pointed out, one of my main goals was to offer an alternative to the “standard” graphq_ppx approach for people who might benefit from it. But if that approach feels right to you, great!