Skip to content

Commit

Permalink
- adding docs for abstract types in relay resolvers
Browse files Browse the repository at this point in the history
Reviewed By: captbaritone

Differential Revision: D65181244

fbshipit-source-id: 119462c2aae4793484575df8aeb20c44a727ef80
  • Loading branch information
lynnshaoyu authored and facebook-github-bot committed Oct 30, 2024
1 parent 065c60b commit 5cccb7b
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 8 deletions.
52 changes: 52 additions & 0 deletions website/docs/guides/relay-resolvers/defining-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,55 @@ export type ProfilePicture = { url: string, height: number, width: number };
:::tip
Generally weak types are used for creating a namespace for a set of fields that ultimately "belong" to a parent object.
:::

### Implementing Abstract Types

Relay Resolver types can implement [abstract types](https://relay.dev/docs/glossary/#abstract-type) defined in the graphql schema. Note, these abstract types can
be defined on your GraphQL server schema OR a [client side schema extension](https://relay.dev/docs/next/guides/client-schema-extensions/).

For example, given the following interface:

```graphql
# IUser.graphql
interface IUser {
name: String
}
```

You could define two (or more) concrete resolver types that implement the IUser interface by adding annotations in the docblock (the same applies for unions).
<FbInternalOnly>
Note, support for abstract types is not available for relay resolvers in Flow syntax (yet).
</FbInternalOnly>

<Tabs
groupId="resolver"
defaultValue="Docblock"
values={fbContent({
internal: [
{label: 'Docblock', value: 'Docblock'},
],
external: [
{label: 'Docblock', value: 'Docblock'},
]
})}>
<TabItem value="Docblock">


```tsx
/**
* @RelayResolver BasicUser implements IUser
*/
export function BasicUser(id: DataID): BasicUserModel {
return { ...BasicUserService.getById(id), name: 'BasicUser1'};
}

/**
* @RelayResolver SpecialUser implements IUser
*/
export function SpecialUser(id: DataID): SpecialUserModel {
return { ...SpecialUserService.getById(id), name: 'SpecalUser1'};
}
```

</TabItem>
</Tabs>
4 changes: 0 additions & 4 deletions website/docs/guides/relay-resolvers/limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ Relay Resolvers are do have some limitations. Here we will collect a list of kno

In a full GraphQL implementation, resolvers would have access to an `info` argument. This argument is not available in Relay Resolvers today.

## No support for abstract types

Today it is not possible to define an interface or union with multiple concrete types using Relay Resolvers. This is something we would like to support in the future, but have not yet implemented.

## All fields must be nullable

Today all resolvers must be typed as nullable in order to support coercing errors to null without having to implement null bubbling. In the future we intend Resolvers to support some version of [strict semantic nullability](https://github.com/graphql/graphql-wg/discussions/1410).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,55 @@ export type ProfilePicture = { url: string, height: number, width: number };
:::tip
Generally weak types are used for creating a namespace for a set of fields that ultimately "belong" to a parent object.
:::

### Implementing Abstract Types

Relay Resolver types can implement [abstract types](https://relay.dev/docs/glossary/#abstract-type) defined in the graphql schema. Note, these abstract types can
be defined on your GraphQL server schema OR a [client side schema extension](https://relay.dev/docs/next/guides/client-schema-extensions/).

For example, given the following interface:

```graphql
# IUser.graphql
interface IUser {
name: String
}
```

You could define two (or more) concrete resolver types that implement the IUser interface by adding annotations in the docblock (the same applies for unions).
<FbInternalOnly>
Note, support for abstract types is not available for relay resolvers in Flow syntax (yet).
</FbInternalOnly>

<Tabs
groupId="resolver"
defaultValue="Docblock"
values={fbContent({
internal: [
{label: 'Docblock', value: 'Docblock'},
],
external: [
{label: 'Docblock', value: 'Docblock'},
]
})}>
<TabItem value="Docblock">


```tsx
/**
* @RelayResolver BasicUser implements IUser
*/
export function BasicUser(id: DataID): BasicUserModel {
return { ...BasicUserService.getById(id), name: 'BasicUser1'};
}

/**
* @RelayResolver SpecialUser implements IUser
*/
export function SpecialUser(id: DataID): SpecialUserModel {
return { ...SpecialUserService.getById(id), name: 'SpecalUser1'};
}
```

</TabItem>
</Tabs>
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ Relay Resolvers are do have some limitations. Here we will collect a list of kno

In a full GraphQL implementation, resolvers would have access to an `info` argument. This argument is not available in Relay Resolvers today.

## No support for abstract types

Today it is not possible to define an interface or union with multiple concrete types using Relay Resolvers. This is something we would like to support in the future, but have not yet implemented.

## All fields must be nullable

Today all resolvers must be typed as nullable in order to support coercing errors to null without having to implement null bubbling. In the future we intend Resolvers to support some version of [strict semantic nullability](https://github.com/graphql/graphql-wg/discussions/1410).
Expand Down

0 comments on commit 5cccb7b

Please sign in to comment.