relay-runtime
Version:
A core runtime for building GraphQL-driven applications.
152 lines (125 loc) • 3.83 kB
text/mdx
id: defining-fields
title: "Defining Fields"
slug: /guides/relay-resolvers/defining-fields/
description: How to define fields for your client state schema using Relay Resolvers
import {FbInternalOnly, fbContent} from 'docusaurus-plugin-internaldocs-fb/internal';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Defining fields on a client type is as simple as defining a resolver function which accepts an instance of your model type as its first argument and returns the field value. Note that the exported function name must match the field name.
## Syntax
Relay resolvers are marked via docblocks above a resolver function. `@relayField` is the tag used to define a field on a type. To define a field on a GraphQL model type `TypeName`:
<Tabs
groupId="resolver"
defaultValue="Docblock"
values={fbContent({
internal: [
{label: 'Docblock', value: 'Docblock'},
{label: 'Flow', value: 'Flow'},
],
external: [
{label: 'Docblock', value: 'Docblock'},
]
})}>
<TabItem value="Docblock">
Add `TypeName` followed by a dot followed by the field definition using GraphQL's schema definition language: https://spec.graphql.org/June2018/#FieldDefinition
```js
/**
* @relayField TypeName.fieldName(arg1: ArgTypeName): FieldTypeName
*/
```
</TabItem>
<TabItem value="Flow">
<FbInternalOnly>
Import and use the Flow type for the object, Relay finds the GraphQL type linked to `TypeName`, and use the function name as the field name
```tsx
import {TypeName} from 'TypeObject';
/**
* @relayField
*/
export function fieldName(user: TypeName): string {
return user.name;
}
```
</FbInternalOnly>
</TabItem>
</Tabs>
A simple field might look something like this:
<Tabs
groupId="resolver"
defaultValue="Docblock"
values={fbContent({
internal: [
{label: 'Docblock', value: 'Docblock'},
{label: 'Flow', value: 'Flow'},
],
external: [
{label: 'Docblock', value: 'Docblock'},
]
})}>
<TabItem value="Docblock">
```tsx
/**
* @relayField User.name: String
*/
export function name(user: UserModel): string {
return user.name;
}
```
</TabItem>
<TabItem value="Flow">
<FbInternalOnly>
```tsx
/**
* @relayField
*/
export function name(user: UserModel): string {
return user.name;
}
```
</FbInternalOnly>
</TabItem>
</Tabs>
:::note
Relay will take care of efficiently recomputing resolvers when any of their inputs (in this case the model instance) change, so you don’t need to worry about memoizing your resolver function.
:::
This is just a simple resolver that reads from the model type and returns a scalar value. To learn about the full menu of capabilities that resolver fields support see:
* [Resolver Return Types](./return-types.mdx)
* [Field Arguments](./field-arguments.mdx)
* [Live Fields](./live-fields.mdx)
* [Derived Fields](./derived-fields.mdx)
<FbInternalOnly>
## Simplified Syntax for Property Lookups
If you have a ["weak" type](./defining-types.mdx#defining-a-weak-type), you can easily define a simple resolver that just returns a property from the underlying model. For example, take a resolver being defined on the `UserModel` that looks like:
```tsx
/**
* @relayField
*/
export function name(user: UserModel): string {
return user.name;
}
```
When defining the weak type, this resolver can by automatically generated by using a docblock with `@gqlField` over the field you want to expose.
```tsx
/**
* @relayType
*/
export type UserModel = {
/**
* @gqlField
*/
name: string,
}
```
You can optionally include a description or `@deprecated` tag in the docblock
```tsx
/**
* @gqlField
* @deprecated Do not use this field anymore
*
* This is a description. Include more information
* about your field here.
*/
```
</FbInternalOnly>