Skip to content

Commit 081b8fb

Browse files
authored
Updates Apollo Server Examples to use Apollo Server 4 & @as-integrations/next (vercel#42771)
Closes vercel#42769 ## Description This PR address vercel#42769 by updating the `api-routes-apollo-server`, `api-routes-apollo-server-and-client` and `api-routes-apollo-server-and-client-auth` examples to use Apollo Server 4 and [@as-integrations/next](https://github.com/apollo-server-integrations/apollo-server-integration-next), which is the Apollo Server Next integration package. The PR also updates the three examples to use Typescript. The functionality of the examples is the same. ## Documentation / Examples - [X] Make sure the linting passes by running `pnpm build && pnpm lint` - [X] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) closes vercel#33545 closes vercel#30082 closes vercel#21984 closes vercel#10413
1 parent 0bc9446 commit 081b8fb

39 files changed

+152
-70
lines changed

examples/api-routes-apollo-server-and-client-auth/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Apollo Server and Client Auth Example
22

3-
[Apollo](https://www.apollographql.com/client/) is a GraphQL client that allows you to easily query the exact data you need from a GraphQL server. In addition to fetching and mutating data, Apollo analyzes your queries and their results to construct a client-side cache of your data, which is kept up to date as further queries and mutations are run.
3+
[Apollo](https://www.apollographql.com/client/) is a GraphQL client that allows you to easily query the exact data you need from a GraphQL server. In addition to fetching and mutating data, Apollo analyzes your queries and their results to construct a client-side cache of your data, which is kept up to date as further queries and mutations are run. The integration with Next and Apollo Server is implemented using the [apollo-server-integration-next](https://github.com/apollo-server-integrations/apollo-server-integration-next) community package.
44

55
In this simple example, we integrate Apollo seamlessly with [Next.js data fetching methods](https://nextjs.org/docs/basic-features/data-fetching) to fetch queries in the server and hydrate them in the browser.
66

examples/api-routes-apollo-server-and-client-auth/apollo/client.js examples/api-routes-apollo-server-and-client-auth/apollo/client.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import { useMemo } from 'react'
2-
import { ApolloClient, InMemoryCache } from '@apollo/client'
2+
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client'
3+
import { SchemaLink } from '@apollo/client/link/schema'
4+
import { schema } from '../apollo/schema'
35
import merge from 'deepmerge'
46

57
let apolloClient
68

79
function createIsomorphLink() {
810
if (typeof window === 'undefined') {
9-
const { SchemaLink } = require('@apollo/client/link/schema')
10-
const { schema } = require('./schema')
1111
return new SchemaLink({ schema })
1212
} else {
13-
const { HttpLink } = require('@apollo/client/link/http')
1413
return new HttpLink({
1514
uri: '/api/graphql',
1615
credentials: 'same-origin',

examples/api-routes-apollo-server-and-client-auth/apollo/resolvers.js examples/api-routes-apollo-server-and-client-auth/apollo/resolvers.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
1-
import { AuthenticationError, UserInputError } from 'apollo-server-micro'
21
import { createUser, findUser, validatePassword } from '../lib/user'
32
import { setLoginSession, getLoginSession } from '../lib/auth'
43
import { removeTokenCookie } from '../lib/auth-cookies'
4+
import { GraphQLError } from 'graphql'
55

66
export const resolvers = {
77
Query: {
8-
async viewer(_parent, _args, context, _info) {
8+
async viewer(_root, _args, context, _info) {
99
try {
1010
const session = await getLoginSession(context.req)
1111

1212
if (session) {
1313
return findUser({ email: session.email })
1414
}
1515
} catch (error) {
16-
throw new AuthenticationError(
17-
'Authentication token is invalid, please log in'
16+
throw new GraphQLError(
17+
'Authentication token is invalid, please log in',
18+
{
19+
extensions: {
20+
code: 'UNAUTHENTICATED',
21+
},
22+
}
1823
)
1924
}
2025
},
@@ -38,7 +43,7 @@ export const resolvers = {
3843
return { user }
3944
}
4045

41-
throw new UserInputError('Invalid email and password combination')
46+
throw new GraphQLError('Invalid email and password combination')
4247
},
4348
async signOut(_parent, _args, context, _info) {
4449
removeTokenCookie(context.res)

examples/api-routes-apollo-server-and-client/apollo/schema.js examples/api-routes-apollo-server-and-client-auth/apollo/schema.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { makeExecutableSchema } from 'graphql-tools'
1+
import { makeExecutableSchema } from '@graphql-tools/schema'
22
import { typeDefs } from './type-defs'
33
import { resolvers } from './resolvers'
44

examples/api-routes-apollo-server-and-client-auth/package.json

+11-3
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,24 @@
66
"start": "next start"
77
},
88
"dependencies": {
9-
"@apollo/client": "^3.0.2",
9+
"@apollo/client": "^3.7.1",
10+
"@apollo/server": "^4.1.1",
11+
"@as-integrations/next": "^1.1.0",
12+
"@graphql-tools/schema": "^9.0.9",
13+
"graphql": "^16.6.0",
1014
"@hapi/iron": "6.0.0",
11-
"apollo-server-micro": "^2.14.2",
1215
"cookie": "^0.4.1",
1316
"deepmerge": "4.2.2",
14-
"graphql": "^14.0.2",
1517
"next": "latest",
1618
"prop-types": "^15.6.2",
1719
"react": "^18.2.0",
1820
"react-dom": "^18.2.0",
1921
"uuid": "8.1.0"
22+
},
23+
"devDependencies": {
24+
"@types/node": "^18.0.2",
25+
"@types/react": "^18.0.15",
26+
"@types/react-dom": "^18.0.6",
27+
"typescript": "^4.7.4"
2028
}
2129
}

examples/api-routes-apollo-server-and-client-auth/pages/api/graphql.js

-17
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ApolloServer } from '@apollo/server'
2+
import { startServerAndCreateNextHandler } from '@as-integrations/next'
3+
import { NextApiRequest, NextApiResponse } from 'next'
4+
import { schema } from '../../apollo/schema'
5+
6+
type ExampleContext = {
7+
req: NextApiRequest
8+
res: NextApiResponse
9+
}
10+
11+
const apolloServer = new ApolloServer<ExampleContext>({ schema })
12+
13+
export default startServerAndCreateNextHandler(apolloServer, {
14+
context: async (req, res) => ({ req, res }),
15+
})

examples/api-routes-apollo-server-and-client-auth/pages/index.js examples/api-routes-apollo-server-and-client-auth/pages/index.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ const Index = () => {
3232
if (viewer) {
3333
return (
3434
<div>
35-
You're signed in as {viewer.email} goto <Link href="/about">about</Link>{' '}
36-
page. or <Link href="/signout">signout</Link>
35+
You're signed in as {viewer.email}. Go to{' '}
36+
<Link href="/about">about</Link> page or{' '}
37+
<Link href="/signout">signout</Link>.
3738
</div>
3839
)
3940
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"lib": ["dom", "dom.iterable", "esnext"],
5+
"allowJs": true,
6+
"skipLibCheck": true,
7+
"strict": false,
8+
"forceConsistentCasingInFileNames": true,
9+
"noEmit": true,
10+
"esModuleInterop": true,
11+
"module": "esnext",
12+
"moduleResolution": "node",
13+
"resolveJsonModule": true,
14+
"isolatedModules": true,
15+
"jsx": "preserve",
16+
"incremental": true
17+
},
18+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "pages/about.js"],
19+
"exclude": ["node_modules"]
20+
}

examples/api-routes-apollo-server-and-client/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Apollo Server and Client Example
22

3-
[Apollo](https://www.apollographql.com/client/) is a GraphQL client that allows you to easily query the exact data you need from a GraphQL server. In addition to fetching and mutating data, Apollo analyzes your queries and their results to construct a client-side cache of your data, which is kept up to date as further queries and mutations are run.
3+
[Apollo](https://www.apollographql.com/client/) is a GraphQL client that allows you to easily query the exact data you need from a GraphQL server. In addition to fetching and mutating data, Apollo analyzes your queries and their results to construct a client-side cache of your data, which is kept up to date as further queries and mutations are run. The integration with Next and Apollo Server is implemented using the [apollo-server-integration-next](https://github.com/apollo-server-integrations/apollo-server-integration-next) community package.
44

55
In this simple example, we integrate Apollo seamlessly with [Next.js data fetching methods](https://nextjs.org/docs/basic-features/data-fetching) to fetch queries in the server and hydrate them in the browser.
66

examples/api-routes-apollo-server-and-client/apollo/client.js examples/api-routes-apollo-server-and-client/apollo/client.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import { useMemo } from 'react'
2-
import { ApolloClient, InMemoryCache } from '@apollo/client'
2+
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client'
3+
import { SchemaLink } from '@apollo/client/link/schema'
4+
import { schema } from '../apollo/schema'
35
import merge from 'deepmerge'
46

57
let apolloClient
68

79
function createIsomorphLink() {
810
if (typeof window === 'undefined') {
9-
const { SchemaLink } = require('@apollo/client/link/schema')
10-
const { schema } = require('./schema')
1111
return new SchemaLink({ schema })
1212
} else {
13-
const { HttpLink } = require('@apollo/client/link/http')
1413
return new HttpLink({
1514
uri: '/api/graphql',
1615
credentials: 'same-origin',

examples/api-routes-apollo-server-and-client/apollo/resolvers.js examples/api-routes-apollo-server-and-client/apollo/resolvers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export const resolvers = {
22
Query: {
3-
viewer(_parent, _args, _context, _info) {
3+
viewer() {
44
return { id: 1, name: 'John Smith', status: 'cached' }
55
},
66
},

examples/api-routes-apollo-server-and-client-auth/apollo/schema.js examples/api-routes-apollo-server-and-client/apollo/schema.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { makeExecutableSchema } from 'graphql-tools'
1+
import { makeExecutableSchema } from '@graphql-tools/schema'
22
import { typeDefs } from './type-defs'
33
import { resolvers } from './resolvers'
44

examples/api-routes-apollo-server-and-client/package.json

+11-4
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,20 @@
66
"start": "next start"
77
},
88
"dependencies": {
9-
"@apollo/client": "^3.0.2",
10-
"apollo-server-micro": "^2.14.2",
9+
"@apollo/client": "^3.7.1",
10+
"@apollo/server": "^4.1.1",
11+
"@as-integrations/next": "^1.1.0",
12+
"@graphql-tools/schema": "^9.0.9",
1113
"deepmerge": "4.2.2",
12-
"graphql": "^14.0.2",
14+
"graphql": "^16.6.0",
1315
"next": "latest",
14-
"prop-types": "^15.6.2",
1516
"react": "^18.2.0",
1617
"react-dom": "^18.2.0"
18+
},
19+
"devDependencies": {
20+
"@types/node": "^18.0.2",
21+
"@types/react": "^18.0.15",
22+
"@types/react-dom": "^18.0.6",
23+
"typescript": "^4.7.4"
1724
}
1825
}

examples/api-routes-apollo-server-and-client/pages/api/graphql.js

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { ApolloServer } from '@apollo/server'
2+
import { startServerAndCreateNextHandler } from '@as-integrations/next'
3+
import { schema } from '../../apollo/schema'
4+
5+
const apolloServer = new ApolloServer({ schema })
6+
7+
export default startServerAndCreateNextHandler(apolloServer)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"lib": ["dom", "dom.iterable", "esnext"],
5+
"allowJs": true,
6+
"skipLibCheck": true,
7+
"strict": false,
8+
"forceConsistentCasingInFileNames": true,
9+
"noEmit": true,
10+
"esModuleInterop": true,
11+
"module": "esnext",
12+
"moduleResolution": "node",
13+
"resolveJsonModule": true,
14+
"isolatedModules": true,
15+
"jsx": "preserve",
16+
"incremental": true
17+
},
18+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
19+
"exclude": ["node_modules"]
20+
}

examples/api-routes-apollo-server/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Consume local Apollo GraphQL schema to create Static Generation export
22

3-
Next.js ships with two forms of pre-rendering: [Static Generation](https://nextjs.org/docs/basic-features/pages#static-generation-recommended) and [Server-side Rendering](https://nextjs.org/docs/basic-features/pages#server-side-rendering). This example shows how to perform Static Generation using a local [Apollo GraphQL](https://www.apollographql.com/docs/apollo-server/) schema within [getStaticProps](https://nextjs.org/docs/basic-features/data-fetching/get-static-props) and [getStaticPaths](https://nextjs.org/docs/basic-features/data-fetching/get-static-paths.md). The end result is a Next.js application that uses one Apollo GraphQL schema to generate static pages at build time and also serve a GraphQL [API Route](https://nextjs.org/docs/api-routes/introduction) at runtime.
3+
Next.js ships with two forms of pre-rendering: [Static Generation](https://nextjs.org/docs/basic-features/pages#static-generation-recommended) and [Server-side Rendering](https://nextjs.org/docs/basic-features/pages#server-side-rendering). This example shows how to perform Static Generation using a local [Apollo GraphQL Server ](https://www.apollographql.com/docs/apollo-server/) schema within [getStaticProps](https://nextjs.org/docs/basic-features/data-fetching/get-static-props) and [getStaticPaths](https://nextjs.org/docs/basic-features/data-fetching/get-static-paths.md). The end result is a Next.js application that uses one Apollo GraphQL schema to generate static pages at build time and also serve a GraphQL [API Route](https://nextjs.org/docs/api-routes/introduction) at runtime. The integration with Next and Apollo Server is implemented using the [apollo-server-integration-next](https://github.com/apollo-server-integrations/apollo-server-integration-next) community package.
44

55
## Deploy your own
66

examples/api-routes-apollo-server/package.json

+11-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,19 @@
77
"start": "next start"
88
},
99
"dependencies": {
10-
"apollo-server-micro": "2.13.1",
11-
"graphql": "15.0.0",
10+
"@apollo/server": "^4.1.1",
11+
"@as-integrations/next": "^1.1.0",
12+
"@graphql-tools/schema": "^9.0.9",
13+
"graphql": "16.6.0",
14+
"graphql-tag": "^2.12.6",
1215
"next": "latest",
1316
"react": "^18.2.0",
1417
"react-dom": "^18.2.0"
18+
},
19+
"devDependencies": {
20+
"@types/node": "^18.0.0",
21+
"@types/react": "^18.0.14",
22+
"@types/react-dom": "^18.0.5",
23+
"typescript": "^4.7.4"
1524
}
1625
}

examples/api-routes-apollo-server/pages/[username].js examples/api-routes-apollo-server/pages/[username].tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@ export async function getStaticProps(context) {
2929
}
3030

3131
export async function getStaticPaths() {
32-
const { users } = await queryGraphql(`
32+
const { users } = (await queryGraphql(`
3333
query {
3434
users {
3535
username
3636
}
3737
}
38-
`)
38+
`)) as { users: { username: string }[] }
39+
3940
return {
4041
paths: users.map(({ username }) => ({
4142
params: { username },

examples/api-routes-apollo-server/pages/api/graphql.js examples/api-routes-apollo-server/pages/api/graphql.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { ApolloServer, gql, makeExecutableSchema } from 'apollo-server-micro'
1+
import { ApolloServer } from '@apollo/server'
2+
import { startServerAndCreateNextHandler } from '@as-integrations/next'
3+
import { makeExecutableSchema } from '@graphql-tools/schema'
4+
import { gql } from 'graphql-tag'
25

36
const typeDefs = gql`
47
type Query {
@@ -10,6 +13,7 @@ const typeDefs = gql`
1013
username: String
1114
}
1215
`
16+
1317
const users = [
1418
{ name: 'Leeroy Jenkins', username: 'leeroy' },
1519
{ name: 'Foo Bar', username: 'foobar' },
@@ -28,12 +32,8 @@ const resolvers = {
2832

2933
export const schema = makeExecutableSchema({ typeDefs, resolvers })
3034

31-
export const config = {
32-
api: {
33-
bodyParser: false,
34-
},
35-
}
36-
37-
export default new ApolloServer({ schema }).createHandler({
38-
path: '/api/graphql',
35+
const server = new ApolloServer({
36+
schema,
3937
})
38+
39+
export default startServerAndCreateNextHandler(server)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"lib": ["dom", "dom.iterable", "esnext"],
5+
"allowJs": true,
6+
"skipLibCheck": true,
7+
"strict": false,
8+
"forceConsistentCasingInFileNames": true,
9+
"noEmit": true,
10+
"esModuleInterop": true,
11+
"module": "esnext",
12+
"moduleResolution": "node",
13+
"resolveJsonModule": true,
14+
"isolatedModules": true,
15+
"jsx": "preserve",
16+
"incremental": true
17+
},
18+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
19+
"exclude": ["node_modules"]
20+
}

0 commit comments

Comments
 (0)