Skip to content

Commit

Permalink
Merge branch 'develop' into support-external-extensions
Browse files Browse the repository at this point in the history
* develop:
  feat: Don't force async if connection resolvers are sync (#707)
  feat: add .asArg for enum, fix default typings (#708)
  chore: Prettier on the codebase for JSDoc formatting (#706)
  docs: cover extendType with jsdocs
  chore(docs): fix nullability yaml frontmatter
  chore(docs): own guide for nullability
  docs: cover objectType with jsdocs (#703)
  chore(docs): fix typo
  chore(docs): fix typo
  chore(docs): fix many things in the tutorial
  chore(docs): fix common to install test deps in tutorial
  • Loading branch information
tgriesser committed Dec 7, 2020
2 parents 0c84992 + 0cff220 commit eb2d118
Show file tree
Hide file tree
Showing 84 changed files with 1,646 additions and 1,448 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/pr.yml
Expand Up @@ -11,7 +11,7 @@ jobs:
with:
node-version: 12.x
- name: Install Dependencies
run: yarn --frozen-lockfile
run: yarn --frozen-lockfile && yarn format:ci
- name: Install GraphQL@14.x
run: yarn add graphql@^14.5.8
- name: Test
Expand All @@ -30,6 +30,9 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: yarn --frozen-lockfile
- name: Check Prettier
if: matrix.os != 'windows-latest'
run: yarn format:ci
- name: Test
run: yarn -s test:ci
- name: Upload coverage to Codecov
Expand Down Expand Up @@ -61,7 +64,7 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: yarn --frozen-lockfile
run: yarn --frozen-lockfile && yarn format:ci
- name: Link
run: yarn link
- name: Example Install
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/trunk.yml
Expand Up @@ -32,6 +32,9 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: yarn --frozen-lockfile
- name: Check Prettier
if: matrix.os != 'windows-latest'
run: yarn format:ci
- name: Test
run: yarn -s test:ci
- name: Upload coverage to Codecov
Expand Down Expand Up @@ -63,7 +66,7 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: yarn --frozen-lockfile
run: yarn --frozen-lockfile && yarn format:ci
- name: Link
run: yarn link
- name: Example Install
Expand All @@ -82,7 +85,7 @@ jobs:
fetch-depth: 0
- uses: actions/setup-node@v1
- name: Install Dependencies
run: yarn --frozen-lockfile
run: yarn --frozen-lockfile && yarn format:ci
- name: Release Canary
env:
NPM_TOKEN: ${{secrets.NPM_TOKEN}}
Expand Down
Expand Up @@ -52,6 +52,10 @@ Sometimes content that isn't core to the current flow but related to it will be

As you progress you'll be writing code, of course. Often you'll have the chance to copy and paste our code, but we strongly suggest if you're just starting out to **write the code yourself**. This will expose you to _experience_ of writing a Nexus app. Things like autocompletion and letting static safety guide your implementations, e.g. inside a GraphQL resolver. Also if you're new to TypeScript getting used to encountering, understanding, and fixing static type errors is essential practice. That said at no time should you feel _frustrated_. If things just aren't working, copy-paste our work as needed. Then, once things _are_ working, taking a moment muck around, break things, fix them again, etc. is almost always time well spent.

### GitHub Repository

Note that there is a GitHub repository at [graphql-nexus/tutorial](https://github.com/graphql-nexus/tutorial) containing the finished code you will build in this tutorial. You can always check this out if you get stuck during the tutorial.

## Wrapping up

Thanks for checking out Nexus, we hope you're as excited to learn about it as we are to show it to you! 🚀
Expand Down
Expand Up @@ -77,17 +77,18 @@ Finally, we'll import this file and pass it down to `makeSchema`

```ts
// api/schema.ts
import { join } from 'path'
+ import * as typeDefs from './graphql'
import { makeSchema } from '@nexus/schema'
import { join } from 'path'
+ import * as types from './graphql'

const schema = makeSchema({
const schema = makeSchema({
- types: []
+ types: typeDefs,
outputs: {
typegen: join(__dirname, '..', 'nexus-typegen.ts'),
schema: join(__dirname, '..', 'schema.graphql')
}
})
+ types,
outputs: {
typegen: join(__dirname, '../nexus-typegen.ts'),
schema: join(__dirname, '../schema.graphql')
}
})
```

</tab>
Expand All @@ -96,15 +97,16 @@ Finally, we'll import this file and pass it down to `makeSchema`

```ts
// api/schema.ts
import { makeSchema } from '@nexus/schema'
import { join } from 'path'
import * as typeDefs from './graphql'
import * as types from './graphql'

const schema = makeSchema({
types: typeDefs,
export const schema = makeSchema({
types,
outputs: {
typegen: join(__dirname, '..', 'nexus-typegen.ts'),
schema: join(__dirname, '..', 'schema.graphql')
}
typegen: join(__dirname, '../nexus-typegen.ts'),
schema: join(__dirname, '../schema.graphql'),
},
})
```

Expand Down Expand Up @@ -151,7 +153,7 @@ We'll start by letting API clients read the drafts of your blog.
```ts
// api/graphql/Post.ts // 1

import { objectType, extendType } from '@nexus/schema'
import { extendType } from '@nexus/schema'

export const PostQuery = extendType({
type: 'Query', // 2
Expand Down Expand Up @@ -179,7 +181,7 @@ type Query {

1. The Query object is a central place in your schema where many other types will appear. Like before with the modular GraphQL types decision we again can decide to be modular here. We could either create a new `api/graphql/Query.ts` module (not modular), or we could _collocate_ the exposure of Post object with its definition in `api/graphql/Post.ts` (modular). Staying consistent with before, we'll take the modular way.
1. To achieve collocation in Nexus we'll use `schema.extendType`. Its API is _very_ similar to `schema.objectType` with the difference that the defined fields are merged into the _targeted_ type.
1. `.nullable` specifies that clients will always get a value for this field. By default, in Nexus, all "output types" (types returned by fields) are nullable. This is for [best practice reasons](https://graphql.org/learn/best-practices/#nullability). In this case though we indeed want to guarantee that a list will always be returned, never `null`.
1. `.nonNull` specifies that clients will always get a value for this field. By default, in Nexus, all "output types" (types returned by fields) are nullable. This is for [best practice reasons](https://graphql.org/learn/best-practices/#nullability). In this case though we indeed want to guarantee that a list will always be returned, never `null`.
If you're ever dissatisfied with Nexus' defaults, not to worry, [you can change them](https://www.nexusjs.org/#/api/modules/main/exports/settings?id=schemanullableinputs).
1. `.list` augments the field's type spec, making it wrapped by a List type. Here, a `[Post]`.
1. The first parameter specifies the field's name, here `drafts`
Expand Down
Expand Up @@ -49,7 +49,28 @@ Now to expose it in our GraphQL context there is two things we need to do:
1. Pass the `db` object to our GraphQL server context
1. Let Nexus know what the type of our context is

Let's first pass our in-memory database to our GraphQL server
We'll begin by creating a new module to hold out context types and constructor.

```bash-symbol
touch api/context.ts
```

```ts
// api/context.ts
import { Db, db } from './db'

export interface Context {
db: Db
}

export function createContext(): Context {
return {
db
}
}
```

Then we'll pass our in-memory database to our GraphQL server

<TabbedContent tabs={['Diff', 'Code']}>

Expand All @@ -58,14 +79,12 @@ Let's first pass our in-memory database to our GraphQL server
```ts
// api/server.ts
import { ApolloServer } from 'apollo-server'
+import { createContext } from './context'
import { schema } from './schema'
+import { db } from './db'

export const server = new ApolloServer({
schema,
+ context: () => ({
+ db
+ })
+ context: createContext
})
```

Expand All @@ -76,55 +95,41 @@ export const server = new ApolloServer({
```ts
// api/server.ts
import { ApolloServer } from 'apollo-server'
import { createContext } from './context'
import { schema } from './schema'
import { db } from './db'

export const server = new ApolloServer({
schema,
context: () => ({
db
})
context: createContext
})
```

</tab>

</TabbedContent>

> **Note** For those familiar with GraphQL, you might be grimacing that we’re attaching static things to the context, instead of using export/import.
> This is a matter of convenience. Feel free to take a purer approach in your apps if you prefer.
Then, let's configure Nexus to know the type of our GraphQL context. We'll create an `api/context.ts` file for that

```ts
// api/context.ts
import { Db } from './db'

export interface Context {
db: Db
}
```

Finally, add the following configuration to the `makeSchema` function of `@nexus/schema` in `api/app.ts`
Finally, let's configure Nexus to know the type of our GraphQL context by adjusting the configuration of the `makeSchema` in our `api/app.ts`.

<TabbedContent tabs={['Diff', 'Code']}>

<tab>

```ts
// api/schema.ts
import { makeSchema } from '@nexus/schema'
import { join } from 'path'
import * as types from './graphql'

export const schema = makeSchema({
types: [],
types,
outputs: {
typegen: join(__dirname, '..', 'nexus-typegen.ts'),
schema: join(__dirname, '..', 'schema.graphql')
},
+ typegenAutoConfig: {
+ sources: [
+ {
+ source: require.resolve("./context"), // 1
+ source: join(__dirname, "./context.ts"), // 1
+ alias: "ContextModule", // 2
+ },
+ ],
Expand All @@ -139,18 +144,20 @@ export const schema = makeSchema({

```ts
// api/schema.ts
import { makeSchema } from '@nexus/schema'
import { join } from 'path'
import * as types from './graphql'

export const schema = makeSchema({
types: [],
types,
outputs: {
typegen: join(__dirname, '..', 'nexus-typegen.ts'),
schema: join(__dirname, '..', 'schema.graphql')
},
typegenAutoConfig: {
sources: [
{
source: require.resolve("./context"), // 1
source: join(__dirname, "./context.ts"), // 1
alias: "ContextModule", // 2
},
],
Expand Down Expand Up @@ -178,7 +185,8 @@ Now let's use this data to re-implement the `Query.drafts` resolver from the pre
```ts
// api/graphql/Post.ts

export const PostQuery = queryType({
export const PostQuery = extendType({
type: 'Query',
definition(t) {
t.list.field('drafts', {
type: 'Post',
Expand All @@ -199,7 +207,8 @@ export const PostQuery = queryType({
```ts
// api/graphql/Post.ts

export const PostQuery = queryType({
export const PostQuery = extendType({
type: 'Query',
definition(t) {
t.list.field('drafts', {
type: 'Post',
Expand Down Expand Up @@ -276,7 +285,8 @@ Let's revise our implementation with GraphQL arguments.
```ts
import { extendType, stringArg } from '@nexus/schema'
import { objectType, extendType, stringArg } from '@nexus/schema'
+import { objectType, extendType, stringArg, nonNull } from '@nexus/schema'

export const PostMutation = extendType({
type: 'Mutation',
Expand Down Expand Up @@ -310,7 +320,7 @@ export const PostMutation = extendType({
```ts
import { extendType, stringArg } from '@nexus/schema'
import { objectType, extendType, stringArg, nonNull } from '@nexus/schema'

export const PostMutation = extendType({
type: 'Mutation',
Expand Down Expand Up @@ -361,8 +371,8 @@ Before we wrap this chapter let's flush out our schema a bit more. We'll add a `
```ts
// api/graphql/Post.ts

import { extendType, intArg, stringArg } from '@nexus/schema'
-import { objectType, extendType, stringArg, nonNull } from '@nexus/schema'
+import { objectType, extendType, stringArg, nonNull, intArg } from '@nexus/schema'

export const PostMutation = extendType({
type: 'Mutation',
Expand Down Expand Up @@ -395,8 +405,7 @@ export const PostMutation = extendType({
```ts
// api/graphql/Post.ts

import { extendType, intArg, stringArg } from '@nexus/schema'
import { objectType, extendType, stringArg, nonNull, intArg } from '@nexus/schema'

export const PostMutation = extendType({
type: 'Mutation',
Expand Down Expand Up @@ -446,7 +455,6 @@ Then, we'll let API clients read these published posts.
```ts
// api/graphql/Post.ts

import { extendType } from '@nexus/schema'

export const PostQuery = extendType({
Expand All @@ -471,7 +479,6 @@ export const PostQuery = extendType({

```ts
// api/graphql/Post.ts

import { extendType } from '@nexus/schema'

export const PostQuery = extendType({
Expand All @@ -494,7 +501,7 @@ export const PostQuery = extendType({

<tab>

```ts
```graphql
type Query {
drafts: [Post]!
+ posts: [Post]
Expand Down

0 comments on commit eb2d118

Please sign in to comment.