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

Start Relay Resolver Docs with basic examples #480

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions rescript-relay-documentation/docs/relay-resolvers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
---
id: relay-resolvers
title: Relay Resolvers
sidebar_label: Relay Resolvers
---

#### Recommended background reading
- [Relay Resolvers](https://relay.dev/docs/guides/relay-resolvers/)


## Enabling Experimental Resolvers
Relay Resolvers are still considered experimental. To use them you must ensure that the `ENABLE_RELAY_RESOLVERS`` runtime feature flag is enabled, and that the `enable_relay_resolver_transform`` feature flag is enabled in your project’s Relay config file.

```js
// relay.config.js
module.exports = {
//...
featureFlags: {
enable_relay_resolver_transform: true,
},

//...
};
```

```js
//SomeComponent.res
RescriptRelay.relayFeatureFlags.enableRelayResolvers = true

@react.component
let make = () => {
//
}
```


## Basic Example
```js
// UserGreetingResolver
/**
* @RelayResolver
*
* @onType User
* @fieldName greeting
* @rootFragment GreetingResolver
Comment on lines +43 to +45
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's a more compact notation now that we could perhaps also show. Can't find a link to it now though.

*
* A User Greeting
*/
type t = string

module Fragment = %relay(`
fragment UserGreetingResolver on User {
firstName
lastName
}
`)

let default = Fragment.makeRelayResolver(({firstName, lastName}) => Some(`Hello ${firstName} ${lastNamee}!`))

```




## Using Relay Resolvers
Relay Resolvers utilize special conventions in order to add a new field onto a type.

Rescript Relay Resolvers actively lean on Rescript's type inference to simplify the resolver boilerplate. Still, a resolver type must be explicitly defined with `type t`.

### FileName
Resolver files must end with the word `Resolver` for the relay compiler to compile them

- ❌ ~~ResolveUserGreeting.res~~
- ❌ ~~GenerateUserGreetingField.res~~
- ✅ UserGreetingResolver.res

### Docblock
The Relay compiler looks for the following fields in any docblocks that includes @RelayResolver:

- **@RelayResolver (required)**
- **@rootFragment (optional)** The name of the fragment read by readFragment
- **@deprecated (optional)** Indicates that the field is deprecated. May be optionally followed text giving the reason that the field is deprecated.

The docblock may also contain free text. This free text will be used as the field’s human-readable description, which will be surfaced in Relay’s editor support on hover and in autocomplete results.
```
/**
* @RelayResolver
*
* @onType User
* @fieldName greeting
* @rootFragment UserGreetingResolver *Note* this matches our filename
*
* The status of a todo
*/
```

### Relay Resolver Conventions
In order for Relay to be able to call a Relay Resolver, it must conform to a set of conventions:

- The resolver must have a type `t` defined.
- The resolver must read its fragment using the special `makeRelayResolver` function.
- The resolver function must be pure.
- The resolver’s return value must be immutable.
- The resolver return type must be of `option<t>`

Unlike server resolvers, Relay Resolvers may return any Rescript value, however it must be wrapped in `Option`. This includes functions, arrays, tuples, variants, etc. However, we generally encourage having Relay Resolvers return scalar values and only returning more complex JavaScript values (like functions) as an escape hatch.

## Passing arguments to resolver fields
For resolvers, we support two ways of defining field arguments:

- **GraphQL:** Arguments that are defined via `@argumentDefinitions`` on the resolver's fragment.
- **JS Runtime:** Arguments that can be passed directly to the resolver function.
You can also combine these, and define arguments on the fragment and on the resolver's field itself, Relay will validate the naming (these arguments have to have different names), and pass GraphQL arguments to fragment, and JS arguments to the resolver's function.

### Defining Resolver field with Fragment Arguments
```js
// UserGreetingResolver.res
/**
* @RelayResolver
* @rootFragment UserGreetingResolver
*/

module Fragment = %relay(`
fragment UserGreetingResolver on User
@argumentDefinitions(someArg: {type: "String"}) {
greeting(someArg: $someArg){
__typename
}
}
`)

let default = Fragment.makeRelayResolver(({greeting}) => Some(greeting.__typemame))
```

### Using Resolver field with arguments for Fragment
```js

module Query = %relay(
`Query MyQuery($id: ID, $greetingText: String) {
node(id:$id)
... on User {
greeting(custonText: $greetingText)
}
}
`
)

@react.component
let make = () => {
let data = Query.use(~variables={
id: "abc123",
someArg:"Waasssaaaap?"
})

switch queryData.node {
| Some(user) => <div> {React.string(user.greeting)} </div>
| None => React.null
}
}
```

### Defining Resolver field with Runtime (JS) Arguments
Relay resolvers also support runtime arguments that are not visible/passed to fragments, but are passed to the resolver function itself.

You can define these fragments using GraphQL’s Schema Definition Language in the @fieldName

```
//TODO

```
1 change: 1 addition & 0 deletions rescript-relay-documentation/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module.exports = {
"interfaces",
"input-objects",
"interacting-with-the-store",
"relay-resolvers"
],
"API Reference": ["api-reference", "relay-environment"],
Guides: [
Expand Down
Loading