Guides

Schema

Overview

This is the Nexus component guide. Here you will find concepts explained and a survey of how to use the API. If you are not familiar with Nexus this is a good document to read. If you are familiar, then API Docs may be of more use to you.

GraphQL type builders

We will now begin exploring the GraphQL schema building parts of the schema component. Having prior knowledge of GraphQL language itself will greatly help. If you are new to GraphQL you may want to read some of the resources listed below.

Object Type

graphql.org Object Types

Basic anatomy

1 objectType({
2// A type Builder method -------------^
3 name: 'Foo',
4// The name of this type ----------------------^
5 definition(t) {
6// The type definition block -----------^ |
7// Where fields are defined |
8// |
9// Object of Object Type Field --------------------^
10// Builder methods
11 t.field('bar', {
12// A field builder method ------------------^ |
13// The name of this field -------------------------^
14 type: 'Bar',
15// The type of this field -------------------------^
16 resolve(parent, args, ctx, info) {
17// The method called to return a -----------^ | | | |
18// value for this field when queried | | | |
19// | | | |
20// The backing data model for Foo ------------------^ | | |
21// | | |
22// The client arguments to this field ----------------------^ | |
23// | |
24// Contextual data for this request ------------------------------^ |
25// Shared across all resolvers |
26// |
27// Technical detail about this request --------------------------------^
28// E.g. client's query AST
29
30// Your logic to return a value ------------> ...
31// for this field
32 },
33 })
34
35 t.string('qux')
36// A scalar-type convenience builder -------^ |
37// |
38// No resolver means Nexus returns the -------------^
39// `qux` property from the backing data model
40
41 },
42 })

Scalar fields

1objectType({
2 name: 'Alpha',
3 definition(t) {
4 t.id('a')
5 t.string('b')
6 t.int('c')
7 t.float('d')
8 t.boolean('e')
9 },
10})
1type Alpha {
2 a: ID!
3 b: String!
4 c: Int!
5 d: Float!
6 e: Boolean!
7}

Relational fields

1objectType({
2 name: 'Alpha',
3 definition(t) {
4 t.field('beta', {
5 type: 'Beta',
6 resolve() {
7 return { foo: 'bar' }
8 },
9 })
10 },
11})
12objectType({
13 name: 'Beta',
14 definition(t) {
15 t.string('foo')
16 },
17})
1type Alpha {
2 beta: Beta!
3}
4
5type Beta {
6 foo: String!
7}
Lists and nullability

The following demonstration assumes the Nexus nullability defaults.

1objectType({
2 name: 'Alpha',
3 definition(t) {
4 t.id('a')
5 t.list.id('b')
6 t.nonNull.list.id('c')
7 t.list.nonNull.id('d')
8 t.nonNull.list.nonNull.id('e')
9 },
10})
1type Alpha {
2 a: ID
3 b: [ID]
4 c: [ID]!
5 d: [ID!]
6 e: [ID!]!
7}

Entrypoint types

Enum type

Enum types are a scalar with a finite set of allowed values. They can be used as argument types and as field types.

graphql.org Enumeration Types docs

1enumType({
2 name: 'Alpha',
3 members: ['Zeta', 'Yolo'],
4})
1enum Alpha {
2 Zeta
3 Yolo
4}

Example: As argument type and field type

1queryType({
2 definition(t) {
3 t.field('anyAlpha', {
4 type: 'Alpha',
5 resolve(t) {
6 return Math.random() > 0.1 : 'Zeta' : 'Yolo'
7 }
8 })
9 t.field('alphas', {
10 type: list('Alpha'),
11 args: {
12 except: arg({
13 type: list(nonNull("Alpha")),
14 })
15 },
16 resolve(_root, args) {
17 return ['Zeta', 'Yolo'].filter(alpha => {
18 return !args.except.includes(alpha)
19 })
20 }
21 })
22 }
23})
1type Query {
2 anyAlpha: Alpha!
3 alphas(except: [Alpha!]!): [Alpha!]!
4}
1query {
2 anyAlpha
3 alphas(except: ["Zeta"])
4}
1{
2 "data": {
3 "anyAlpha": "Zeta",
4 "alphas": ["Yolo"]
5 }
6}

Union Type

🚧 Work in progress.

Interface Type

🚧 Work in progress.

Field Arguments

🚧 Work in progress.

Input Object Type

🚧 Work in progress.

Lists

🚧 Work in progress.

Descriptions

🚧 Work in progress.

Deprecations

🚧 Work in progress.

Data Modelling

As the API author, there are three design tasks you will invariable perform over and over again:

  1. Create data types that model logical entities and concepts in your business domain.
  2. Define connections between these data types that model how logical entities and concepts relate in your business domain.
  3. Define entrypoints which allow traversal into this graph of data.

This is an iterative process that can generally be seen as an finite loop wherein your team gradually refines and expands (or contracts!) the data graph as you respond to changing client app needs, business needs, and so on. Data modelling is hard work. For one thing it is a subtle art, occasionally underappreciated. There are typically multiple ways to model any one thing and competing tradeoffs that leave no obvious winner abound. If the process of data modelling itself or data modelling in GraphQL is new to you, you may find this book by Marc-Andre Giroux helpful: Production Ready GraphQL.

Type-safety

Nexus is designed to be nearly 100% type-safe by default. It can automatically type your resolvers args and context, but there's one thing it cannot do without your help: knowing the types that come from your data-sources (such as your database).

By default, Nexus will generate types based on your GraphQL schema. However, the data that flows through your resolvers can be completely different than what your GraphQL Schema expresses.

If that's the case, you will need to tell Nexus what the shape of this data is thanks to the Source Types.

You can read more about them here.

Edit this page on Github