graphql_ppx_re really works great for us. Due to the type system you don’t really need fragments to prevent under fetching. It’s still easier overfetch, and fragments make for a nicer DX. I’m actually interested to improve fragment support in graphql_ppx_re, and have some implementation ideas.
So you are only using query and pass the data into into the children as props?
I thought about that approach too, but that would remove the colocation of data and implementation, which i would really miss.
Do you need any help with improving fragment support? I would be interested to help out (if i can).
Yes, but you are passing the data as props anyway even when you are using fragments right (or am I missing something). I do agree it’s nice to colocate data requirements with the components that receive the data, and miss that too.
Also definitely check out @zth’s reason-relay if you can still choose the Graphql client. It’s super awesome, and the relay compiler is so powerful! Especially they are very early with adopting Suspense (nothing like that in Apollo land unfortunately).
We already adopted Apollo, so currently not an option for us. The upside of graphql_ppx_re/reason-apollo-hooks is that no code needs to be generated, as everything happens in a PPX.
I don’t specifically need help at the moment, but if you are interested you can start a PR, happy to collaborate, otherwise I’l start it at some point and it would be great if you could chime in on the PR. I am currently working on two PR’s to improve graphql_ppx_re:
And a non-published one that adds tagged template literal support for better integration in the ecosystem, specifically building it for Gatsby integration, but it would make Apollo integration also better because it would allow for query extraction in a manifest.
So progressively I am getting to know the code base and it will be easier to tackle something like fragments. (The code base is pretty tricky to get into, as there is so much happening, and almost no documentation. Also PPX-s are hard to understand and almost no documentation around how to write a PPX. Not even a reference documentation.
@zth reason-relay looks super cool, can’t wait to try it out!
Does the (unfinished) Using with schemas that don’t conform to the Relay spec docs mean the server doesn’t need to be Relay-compatible if I can make do without the utilities for graphql connections (easy pagination?) and refetching? I haven’t had the chance to use Relay before, and I’m not sure how much Relay depends on Relay-spec-compliant servers for its core functionality. I’m interested in using reason-relay with Hasura for a subscription-heavy app.
@osener sorry for my late reply, I totally missed this!
So, basically yes, you can use ReasonRelay with any schema if you don’t care about pagination and some refetching abilities. I say some because you can still refetch fragments that are on the root Query type, so some refetching will work.
If you don’t have globally unique IDs you’ll also need to supply a getDataId function to the environment, where you combine __typename and the actual id to make the data id. Happy to provide an example if needed! I’ll also work more on that section of the docs soon to clarify things.
A subscription heavy app should work well even without conforming to the spec, probably only need to set up getDataId, but please try it and let me know!
I’m also working on updating the ReasonRelay docs as I just published a new version that uses records instead of Js.t (which means you can now pattern match properly) and automatically converts nullable/enums/unions, which should greatly simplify things!
@bozhidar so, doing a fully Relay compliant server (fun fact: the Relay spec was actually recently promoted to official best practices for GraphQL, rather than just a spec for Relay) doesn’t really require any support from frameworks (even though that can of course simplify things). It means the following:
Globally unique IDs, which basically mean that if an object has an id prop, it should be globally unique. This really make sense if you think about it - you’re not in a database table here contextually, you’re in a graph of nodes, where each node should be possible to identify somehow.
It’s commonly done by combining the object typename with it’s id and base64-encoding the result. Relay doesn’t care how it looks as long as the ID is globally unique. This should be easily doable in any setting.
Connections. Connections are just a convention for how to structure pagination. This means that you could use anything “behind the scenes” for pagination using connections. Connections in the spec allow paginating both backwards and forwards, which scare a lot of people - just don’t implement backwards pagination if you don’t need it. Also, another tip from experience: Doing normal offset/limit based pagination behind the scenes is totally fine. Connections allow for a very optimized pagination by using cursors etc, but no need to overcomplicate things - a cursor could just as easily be an index in an array, a set of stringified current parameters, an offset or anything else the server can use to continue paginating.
The Node interface. This means that any object that implement the Node interface has an id prop that’s globally unique and can be used to refetch that particular node through a unified node(id: ID!) prop on the schema root. This also scares many people, but it’s not that complicated. The node prop takes an id, and that ID is what you set it up to be in point 1 above. Let’s say it’s a base64 encoded combination of typename and database id. In the handler for node you’d then decode the base64, split the result into typename and database id, and viola, you know what type (typename) you’ll need to fetch a single node of, and you know what id of it to fetch. Really not that complicated. Also something that you don’t need a particular framework or language to implement, it’s just a GraphQL interface with some additional logic in the resolver.
Sorry for the wall of text, just figured I’d put this here in case anyone else is interested in this too. My experience is that people way overestimate how complex the Relay spec is to implement, or that it’s a complicated own thing of it’s own entirely. Just wanted to write a little about that.
I’ve worked on a Django GraphQL server that complied to the described ID pattern. The front end was using Apollo and I knew that these base64 encoded combinations of type and id are related to Relay, I was just interested what else is specified by Relay and how much do web frameworks comply to this specification. It makes sense for most GraphQL or RESTfull apps to implement unique IDs and pagination.
I am also interested if:
The Relay client offers some advantages to Apollo and
ReasonRelay is a connection library to JS Reason, or is it a client completely written in Reason?
Elixir’s Graphql library Absinthe has a module for writing Relay compatible server. More info can be found here.