jeddeloh / rescript-apollo-client

ReScript bindings for the Apollo Client ecosystem
MIT License
126 stars 18 forks source link

Is there a way to bind graphql query responses to existing record types #105

Closed Pet3ris closed 3 years ago

Pet3ris commented 3 years ago

Hi There,

I couldn't find if it's possible to bind to existing record types in hooks examples but have use a similar feature with reason-apollo-hooks.

In reason-apollo-hooks, you used to be able to annotate queries like this:

query myQuery {
  vectorType @bsRecord {
    x
    y
  }
}

This would prompt the compiler to look for a record type named vectorType and bind that to GraphQL responses.

Trying to do the same thing in rescript-apollo results in type errors when parsing GraphQL responses:

  This has type:
    array<
  MyQuery.MyQuery_inner.t_myQuery_Type_subtype,
>

  But somewhere wanted:
    array<ReactHooksTemplate.Type.subtype>

Is there another way to explicitly bind graphql queries to records types that exist in my application?

Pet3ris commented 3 years ago

I came across this: https://github.com/reasonml-community/graphql-ppx/issues/187#issuecomment-672970202.

Does this mean that I should be using the GraphQL generated type in my application and perhaps type aliasing it?

jfrolich commented 3 years ago

Type aliasing, or writing a conversion function is safer than ppxAs (the alternative of bsRecord which is basically an Obj.magic).

Pet3ris commented 3 years ago

I managed to finish the migration, so typing up all the insights you've shared in one place.

Quick guide to moving from old @bsRecord uses in graphql-ppx to new graphql-ppx

This is technically the "unsafe" path but allows you to reuse existing records as much as possible and only minimally change existing code. I had to use this since my records all had @decco annotations and I wanted to keep using them. It's probably better to do what @jfrolich recommended and go with the GraphQL generated types.

Step 1: Replace all instances of type @bsRecord with type @ppxAs(type: "type") in your GraphQL

Step 2: If asked to provide __typename, note that this happens if apollo mode is enabled. To stop this, see this issue: https://github.com/reasonml-community/graphql-ppx/issues/252

Step 3: If polymorphic variants are breaking, note that new graphql-ppx offers a catch-all variant. You have two options here:

If doing the latter and you had a @decco annotation to your variant type, you can use the following amendment to fix serialization/deserialization: https://github.com/reasonml-labs/decco/issues/39#issuecomment-815899303.

Everything else should work fine.