---
title: 'Source Types'
---

## Source Types in theory

As you begin to implement a schema for the first time you will notice something that may not have been obvious at first. The data that the client sees in the data graph is _not_ the same data flowing through the internal resolvers used to fulfill that graph. The client sees the API types but the API author deals with something else, _Source Types_.

To understand the concept better, let's assume the following GraphQL query:

```graphql
{
  user {
    fullName
  }
}
```

Here is an example of resolution for that query as it would be seen roughly from a GraphQL type _only_ point of view.

![](/docs/assets/source-type-diagram-1.png)

When a field's type is an object, then the field's resolver returns a Source Type. Concretely this might for example be a plain JavaScript object containing node/row/document data from a database call. This Source Type data is in turn passed down to all the object type's own field resolvers.

Here is the above diagram updated to include Source Types now.

![](/docs/assets/source-type-diagram-2.png)

Here is a step-by-step breakdown of what is going on:

1. Client sends a query
2. The field resolver for `Query.user` runs. Remember `Query` fields (along with `Subscription`, `Mutation`) are _entrypoints_, also known as _root fields_ because they are on [_Root Types_](https://graphql.org/learn/execution/#root-fields-resolvers).
3. Within this resolver, the database client fetches a user from the database. The resolver returns this data. Keep in mind that at this point, this data _may_ be completely different than what the GraphQL API will resolve at the end.
   ```ts
   // Field of `Query` type
   t.field('user', {
     resolve(source, args, ctx, info) {
       //                            ^---- as: User (Source Type)
       return { firstname: 'Foo', lastname: 'Bar' } // fake db record
     }
   })
   ```
4. Resolution continues since the type of `Query.user` field is an object, not a scalar. As such its own fields need resolving. The fields that get resolved are limited to those selected by the client, in this case: `fullName`. This field resolver run. Its `source` argument is the user model data fetched in step 3. _This is the Source Type data for the GraphQL `User` object_.

   ```ts
   // Field of `User` type
   t.field('fullName', {
     resolve(source, args, ctx, info) {
       //     ^------------------------------- as: User (Source Type)
     },
   }
   ```

Hopefully you can see how the GraphQL types seen by the client are distinct from the Source Types flowing through the resolvers. Below, you can find a code sample of how the implementation of this schema might look like.

<details>
<summary>See code implementation</summary>

```ts
import { queryType, objectType } from 'nexus'

export const Query = queryType({
  definition(t) {
    t.field('user', {
      type: 'User',
      args: {
        id: nonNull(idArg()),
      },
      resolve(_, { id }, { db }) {
        return db.fetchUser({ where: { id } })
      },
    })
  },
})

export interface UserSourceType {
  firstname: string
  lastname: string
}

export const User = objectType({
  name: 'User',
  sourceType: {
    path: __filename,
    name: 'UserSourceType'
  },
  definition(t) {
    t.string('fullName', {
      resolve(source) {
        return source.firstname + source.lastname
      },
    })
  },
})
```

</details>

## Source Types in Nexus

In Nexus, a Source Type can expressed as an `interface`, a `class`, a `type` alias or an `enum`.

Below are examples of valid Source Types:

```ts
export interface UserEntity {
  id: string
  name: string
}

export class Post {
  id: string
  title: string
}

export type CommentModel = {
  id: string
  body: string
}

export enum Color {
  RED
  GREEN
  BLUE
}
```

There are many ways you can configure your Source Types depending on your use-cases. We'll go over each of the available options.

### GraphQL Schema Strategy (default)

When you first begin creating your schema, you may have objects without Source Types setup. In these cases Nexus infers that the Source Type is an exact match of the GraphQL type. Take this schema for example:

<!-- prettier-ignore -->
```ts
// Nexus infers the Source Type of:
//
// { fullName: string, age: number } ---> |
//                                        |
object({                               // |
  name: 'User',                        // |
  definition(t) {                      // |
    t.string('fullName', {             // |
      resolve(user) {                  // |
//            ^-------------------------- | 
        return user.fullName           // |
      },                               // |
    })                                 // |
    t.int('age', {                     // |
      resolve(user) {                  // |
//            ^-------------------------- |
        return user.age                // |
      },                               // |
    })                                 // |
  },                                   // |
})                                     // |
                                       // |
queryType({                            // |
  definition(t) {                      // |
    t.list.field('users', {            // |
      type: 'User',                    // |
      resolve() {                      // |
        return [/**/]                  // |
//               ^----------------------- |
      },
    })
  },
})
```

This may suffice well enough for some time, but most apps will eventually see their GraphQL and Source Types diverge. Once this happens, you can tell Nexus about it using one of the solutions explained below.

### Globally configure Source Types

Configuring your Source Types globally is the recommended way in most cases. Typically, your Source Types will come from your database model types (also called entities), or will be generated by your ORM.

When that's the case, you can configure Nexus to automatically map your Source Types to your GraphQL Object types based on their name.

This is all done in the `sourceTypes` option of `makeSchema`.

#### Exact Matching Strategy

When configured, Nexus will automatically map the Source Types that have the same name as your GraphQL Object types.

Let's see how that works:

```ts
// ./db.ts

export interface User {
// ^-------------^---------- Export your Source Type (required)
//               |---------- Name of your Source Type which will be extracted by Nexus
  firstName: string
  lastName: string
}

export interface Post {
// ^-------------^---------- Export your Source Type (required)
//               |---------- Name of your Source Type which will be extracted by Nexus
// ...
}

export interface Comment {
// ^-------------^---------- Export your Source Type (required)
//               |---------- Name of your Source Type which will be extracted by Nexus
// ...
}

// ./schema.ts

import { makeSchema, objectType, queryType } from 'nexus'
import * as path from 'path'

const User = objectType({
  name: 'User',
  //      ^-------------- Name of your GraphQL Object type which will be matched against
  definition(t) {
    t.string('fullName', {
      resolve(user) {
        //      ^------------------------ as: User
        return user.firstName + ' ' + user.lastName
      }
    })
  }
})

const Query = queryType({
  definition(t) {
    t.list.field('users', {
      type: User,
      resolve(_parent, args, ctx) {
        // ...                   ^------- return as: User[]
      }
    })
  }
})

const schema = makeSchema({
  types: [User, Query],
  sourceTypes: {
    modules: [{
      module: path.join(__dirname, 'db.ts'),
      //       ^---------------------- Path to the file containing your Source Types
      alias: 'db'
      //      ^----- Arbitrary unique name used as alias to import your Source Types.
      //             eg: import * as <alias> from <source>
      //             Make sure to use unique aliases if you have multiple sources
    }]
  }
})
```

In the example above, since the Source Type `interface User` matches the name of the `User` GraphQL Object type, Nexus will use the `interface User` as Source Type for the `User` GraphQL Object type.

#### Pattern Matching Strategy

It is however possible that your Source Types don't exactly match the name of your GraphQL Object type but follow a convention.

For instance:

- Source Type `class UserModel {}` -> GraphQL Object type `User`
- Source Type `class PostModel {}` -> GraphQL Object type `Post`
- Source Type `class CommentModel {}` -> GraphQL Object type `Comment`

In that case, you can configure your `source` to teach Nexus about your convention.

To extract Source Types, Nexus runs regexes against your literal source code. The regexes used by default is:

```ts
new RegExp(`(?:interface|type|class|enum)\\s+(${type.name})\\W`, "g")
```

Your regular expression must capture a group containing the TypeScript type name of the Source Type.
Below is a complete and annotated example to illustrate the system

```ts
//db.ts

export class UserModel {
// ^-------------^---------- Export your Source Type (required)
//               |---------- Name of your Source Type which will be extracted by Nexus
  firstName: string
  lastName: string
}

export class PostModel {
// ^-------------^---------- Export your Source Type (required)
//               |---------- Name of your Source Type which will be extracted by Nexus
// ...
}

export class CommentModel {
// ^-------------^---------- Export your Source Type (required)
//               |---------- Name of your Source Type which will be extracted by Nexus
// ...
}

// schema.ts
import { makeSchema, objectType, queryType } from 'nexus'
import * as path from 'path'

const User = objectType({
  name: 'User',
  //      ^-------------- Name of your GraphQL Object type which will be matched against
  definition(t) {
    t.string('fullName', {
      resolve(user) {
        //      ^------------------------ as: UserModel
        return user.firstName + ' ' + user.lastName
      }
    })
  }
})

const Query = queryType({
  definition(t) {
    t.list.field('users', {
      type: User,
      resolve(_parent, args, ctx) {
        // ...                   ^------- return as: UserModel[]
      }
    })
  }
})

const schema = makeSchema({
  types: [User, Query],
  sourceTypes: {
    modules: [{
      module: path.join(__dirname, 'db.ts'),
      //       ^----------------------------- Path to the file containing your Source Types
      alias: 'db',
      //      ^------------------------------ Name used as alias for Nexus to import your Source Types. eg: import * as <name> from <path>
      typeMatch(type, defaultRegex) {
      //         ^--------^---------------- GraphQL Named type to match against your Source Types
      //                  |---------------- Default regex used to match your GraphQL types against your Source Types
        return new RegExp(`(?:interface|type|class|enum)\\s+(${type.name}Model)\\W`, 'g')
      //            ^---------------------- New regex which will match `UserModel` with `User`, etc..
      },
    }]
  }
})
```

You can also use multiple regexes to extract your Source Types by returning an array of regexes.

In this case, each regex will be run against your source code in the order in which you defined them.

> Note: The first regex to match match will be used.

```ts
const schema = makeSchema({
  sourceTypes: {
    modules: [{
      module: path.join(__dirname, 'db.ts'),
      alias: 'db',
      typeMatch(type, defaultRegex) {
        return [
          defaultRegex,
          //    ^---------------- Pass in the default Regex to keep the default behavior
          new RegExp(`(?:interface|type|class|enum)\\s+(${type.name}Model)\\W`, 'g'),
          // new RegExp(...), -> Add more regexes if you have even more convention
        ]
      },
    }]
  }
})
```

#### Manual Mapping Strategy

If you happen to have Source Types names that can't be matched against your GraphQL Object type names using a RegEx, there are two solutions.

The first solution is especially useful when most of your types _can be matched using a RegEx_ but you only have a couple of types that can't. In that case, the `mapping` can help you.

When provided, it will be used for the Source Types rather than the auto-resolve mechanism of `sources`. It's also useful as an override for one-off cases or for scalar Source Types.

```ts
//db.ts

export class SomeRandomName {
// ^-------------^------- Export your Source Type (required)
//               |------- Name of your Source Type that you'll use for the manual mapping
// ...
}

// schema.ts
import { makeSchema, objectType } from 'nexus'
import * as path from 'path'

const User = objectType({
  name: 'User',
  //      ^-------------- Name of your GraphQL Object type which will be matched against
  definition(t) {
    // ...
  }
})

const schema = makeSchema({
  sourceTypes: {
    modules: [{
      module: path.join(__dirname, 'db.ts'),
      //       ^---------------- Path to the file containing your Source Types
      alias: 'db',
      //      ^----------------- Name used as alias for Nexus to import your Source Types.
      //                         eg: import * as <source> from <alias>
    }],
    mapping: {
      User: 'db.SomeRandomName'
    // ^-----^------^---------- GraphQL type name
    //       |------|---------- Alias of the source where the Source Type is defined
    //              |---------- Source Type name to use for the `User` GraphQL type name
    }
  }
})
```

However, if _none of your Source Types names can match your GraphQL Object type names_ using a RegEx, we suggest you to use the [local Source Types configuration](#locally-configure-source-types).

#### Debugging Source Types matching

Nexus will not output any errors if your Source Types aren't found.

That being said, if you happen to have some Source Types that are not picked up by Nexus, you can enable the `debug` flag in the `sourceTypes` configuration.

Nexus will output debug logs, giving your detailed information about which Source Types were found, which were not, and why.

```ts
import { makeSchema } from 'nexus'

const schema = makeSchema({
  // ...
  sourceTypes: {
    // ...
    debug: true
  }
})
```



### Locally configure Source Types

We typically see two use-cases for using the local configuration of Source Types:

- When your Source Type names can't be matched against your GraphQL Object type names
- When you simply prefer keeping your Source Types next to your Object type definition

To do so, you can use the `sourceType` property as explained below:

```ts
import { objectType, queryType } from 'nexus'

export interface MyDBUser {
  // |           ^-------------------- Create your Source Type
  // ^-------------------------------- Export your Source Type (required)
  firstName: string
  lastName: string
  birthDate: number
}

export const User = objectType({
  name: 'User',
  sourceType: {
    module: __filename,
    //         ^---------------------- Tell Nexus where the Source Type is.
    export: 'MyDBUser'
    //         ^---------------------- Tell Nexus the name of the exported Source Type.
  },
  definition(t) {
    t.string('fullName', {
      resolve(user) {
        //    ^----------------------- as: MyDBUser
        return user.firstName + ' ' + user.fullName
      },
    })
    t.int('age', {
      resolve(user) {
        //    ^------------------------ as: MyDBUser
        return yearsSinceUnixTimestamp(user.birthDate)
      },
    })
  },
})

export const Query = queryType({
  definition(t) {
    t.list.field('users', {
      type: 'User',
      resolve(_source, args, ctx) {
        //                       ^------- return as: MyDBUser[]
        return ctx.db.user.getMany()
      },
    })
  },
})
```
