Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Generating the Client Resolver Schema from TypeScript Types #4768

Open
evanyeung opened this issue Aug 12, 2024 · 0 comments
Open

Support Generating the Client Resolver Schema from TypeScript Types #4768

evanyeung opened this issue Aug 12, 2024 · 0 comments

Comments

@evanyeung
Copy link
Contributor

Relay Resolvers are a relatively new feature to Relay that allows for augmenting the GraphQL schema on the client side. In contrast to client schema extensions, Relay Resolvers include an implementation for computing a new field or model. This allows for backing Relay with an external, client-side data source or computing fields based on other fields.

Currently, defining a Relay Resolver feels redundant when using a typed language. The docblock syntax used to define types and fields includes the GraphQL typenames, which often are one-to-one with the types in the TypeScript/Flow/etc. In implementation first schemas, for example Grats, the schema types are pulled directly out of the definition, reducing the amount of boilerplate and making it impossible for the schema and implementation to get out of sync.

We already have this working in Flow (see https://github.com/facebook/relay/blob/main/compiler/crates/relay-schema-generation/src/lib.rs) and would also like to support TypeScript.

Current Flow Implementation

We use the Hermes parser to generate an AST with Rust bindings. This AST is traversed in relay-schema-generation/src/lib.rs to build an IR representing the models and fields for the resolvers. We use two passes in this file: the first one collects all the models and fields and the second pass connects the fields to the models. This IR is the same as the docblock IR used to generate Resolvers from docblock comments which means it has a few quirks to work around. However, it is easier to understand than directly generating a GraphQL Schema and already has the necessary Relay codegen set up. In the future, we may directly generate GraphQL Types.

Steps to Add TypeScript Support

The simplest way we can see of adding TS support is to just map the TS nodes to the same ESTree nodes as their equivalent Flow nodes. For the simple types supported by Relay, each TS node should have a corresponding Flow node. This means the only changes necessary would be in the Hermes parser.

Future Work

While this solution should work for TypeScript, supporting more compile-to-JS languages could not be done in Hermes. Creating a well defined API directly in the GraphQL schema definition language (SDL) would be a more flexible solution. The GraphQL SDL is well defined, contains enough flexibility to add metadata necessary to run resolvers, and is serializable to easily pass the information from language specific compilers to the Relay compiler. An example of the current SDL output can be found at

favorite_page: ClientPage @relay_resolver(has_output_type: true, import_name: "favorite_page", import_path: "/path/to/test/fixture/terse-relay-resolver-with-output-type.js", fragment_name: "myRootFragment") @resolver_source_hash(value: "6debf0d3b679b66e8d0c58dbdb4d422d")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant