Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates Apollo Server Examples to use Apollo Server 4 & @as-integrations/next #42771

Merged
merged 4 commits into from Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,6 +1,6 @@
# Apollo Server and Client Auth Example

[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.
[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.

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.

Expand Down
@@ -1,16 +1,15 @@
import { useMemo } from 'react'
import { ApolloClient, InMemoryCache } from '@apollo/client'
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client'
import { SchemaLink } from '@apollo/client/link/schema'
import { schema } from '../apollo/schema'
import merge from 'deepmerge'

let apolloClient

function createIsomorphLink() {
if (typeof window === 'undefined') {
const { SchemaLink } = require('@apollo/client/link/schema')
const { schema } = require('./schema')
return new SchemaLink({ schema })
} else {
const { HttpLink } = require('@apollo/client/link/http')
return new HttpLink({
uri: '/api/graphql',
credentials: 'same-origin',
Expand Down
@@ -1,20 +1,25 @@
import { AuthenticationError, UserInputError } from 'apollo-server-micro'
import { createUser, findUser, validatePassword } from '../lib/user'
import { setLoginSession, getLoginSession } from '../lib/auth'
import { removeTokenCookie } from '../lib/auth-cookies'
import { GraphQLError } from 'graphql'

export const resolvers = {
Query: {
async viewer(_parent, _args, context, _info) {
async viewer(_root, _args, context, _info) {
try {
const session = await getLoginSession(context.req)

if (session) {
return findUser({ email: session.email })
}
} catch (error) {
throw new AuthenticationError(
'Authentication token is invalid, please log in'
throw new GraphQLError(
'Authentication token is invalid, please log in',
{
extensions: {
code: 'UNAUTHENTICATED',
},
}
)
}
},
Expand All @@ -38,7 +43,7 @@ export const resolvers = {
return { user }
}

throw new UserInputError('Invalid email and password combination')
throw new GraphQLError('Invalid email and password combination')
},
async signOut(_parent, _args, context, _info) {
removeTokenCookie(context.res)
Expand Down
@@ -1,4 +1,4 @@
import { makeExecutableSchema } from 'graphql-tools'
import { makeExecutableSchema } from '@graphql-tools/schema'
import { typeDefs } from './type-defs'
import { resolvers } from './resolvers'

Expand Down
14 changes: 11 additions & 3 deletions examples/api-routes-apollo-server-and-client-auth/package.json
Expand Up @@ -6,16 +6,24 @@
"start": "next start"
},
"dependencies": {
"@apollo/client": "^3.0.2",
"@apollo/client": "^3.7.1",
"@apollo/server": "^4.1.1",
"@as-integrations/next": "^1.1.0",
"@graphql-tools/schema": "^9.0.9",
"graphql": "^16.6.0",
"@hapi/iron": "6.0.0",
"apollo-server-micro": "^2.14.2",
"cookie": "^0.4.1",
"deepmerge": "4.2.2",
"graphql": "^14.0.2",
"next": "latest",
"prop-types": "^15.6.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"uuid": "8.1.0"
},
"devDependencies": {
"@types/node": "^18.0.2",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"typescript": "^4.7.4"
}
}

This file was deleted.

@@ -0,0 +1,15 @@
import { ApolloServer } from '@apollo/server'
import { startServerAndCreateNextHandler } from '@as-integrations/next'
import { NextApiRequest, NextApiResponse } from 'next'
import { schema } from '../../apollo/schema'

type ExampleContext = {
req: NextApiRequest
res: NextApiResponse
}

const apolloServer = new ApolloServer<ExampleContext>({ schema })

export default startServerAndCreateNextHandler(apolloServer, {
context: async (req, res) => ({ req, res }),
})
Expand Up @@ -32,8 +32,9 @@ const Index = () => {
if (viewer) {
return (
<div>
You're signed in as {viewer.email} goto <Link href="/about">about</Link>{' '}
page. or <Link href="/signout">signout</Link>
You're signed in as {viewer.email}. Go to{' '}
<Link href="/about">about</Link> page or{' '}
<Link href="/signout">signout</Link>.
</div>
)
}
Expand Down
20 changes: 20 additions & 0 deletions examples/api-routes-apollo-server-and-client-auth/tsconfig.json
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "pages/about.js"],
"exclude": ["node_modules"]
}
2 changes: 1 addition & 1 deletion examples/api-routes-apollo-server-and-client/README.md
@@ -1,6 +1,6 @@
# Apollo Server and Client Example

[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.
[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.

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.

Expand Down
@@ -1,16 +1,15 @@
import { useMemo } from 'react'
import { ApolloClient, InMemoryCache } from '@apollo/client'
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client'
import { SchemaLink } from '@apollo/client/link/schema'
import { schema } from '../apollo/schema'
import merge from 'deepmerge'

let apolloClient

function createIsomorphLink() {
if (typeof window === 'undefined') {
const { SchemaLink } = require('@apollo/client/link/schema')
const { schema } = require('./schema')
return new SchemaLink({ schema })
} else {
const { HttpLink } = require('@apollo/client/link/http')
return new HttpLink({
uri: '/api/graphql',
credentials: 'same-origin',
Expand Down
@@ -1,6 +1,6 @@
export const resolvers = {
Query: {
viewer(_parent, _args, _context, _info) {
viewer() {
return { id: 1, name: 'John Smith', status: 'cached' }
},
},
Expand Down
@@ -1,4 +1,4 @@
import { makeExecutableSchema } from 'graphql-tools'
import { makeExecutableSchema } from '@graphql-tools/schema'
import { typeDefs } from './type-defs'
import { resolvers } from './resolvers'

Expand Down
15 changes: 11 additions & 4 deletions examples/api-routes-apollo-server-and-client/package.json
Expand Up @@ -6,13 +6,20 @@
"start": "next start"
},
"dependencies": {
"@apollo/client": "^3.0.2",
"apollo-server-micro": "^2.14.2",
"@apollo/client": "^3.7.1",
"@apollo/server": "^4.1.1",
"@as-integrations/next": "^1.1.0",
"@graphql-tools/schema": "^9.0.9",
"deepmerge": "4.2.2",
"graphql": "^14.0.2",
"graphql": "^16.6.0",
"next": "latest",
"prop-types": "^15.6.2",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "^18.0.2",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"typescript": "^4.7.4"
}
}

This file was deleted.

@@ -0,0 +1,7 @@
import { ApolloServer } from '@apollo/server'
import { startServerAndCreateNextHandler } from '@as-integrations/next'
import { schema } from '../../apollo/schema'

const apolloServer = new ApolloServer({ schema })

export default startServerAndCreateNextHandler(apolloServer)
20 changes: 20 additions & 0 deletions examples/api-routes-apollo-server-and-client/tsconfig.json
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
2 changes: 1 addition & 1 deletion examples/api-routes-apollo-server/README.md
@@ -1,6 +1,6 @@
# Consume local Apollo GraphQL schema to create Static Generation export

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.
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.

## Deploy your own

Expand Down
13 changes: 11 additions & 2 deletions examples/api-routes-apollo-server/package.json
Expand Up @@ -7,10 +7,19 @@
"start": "next start"
},
"dependencies": {
"apollo-server-micro": "2.13.1",
"graphql": "15.0.0",
"@apollo/server": "^4.1.1",
"@as-integrations/next": "^1.1.0",
"@graphql-tools/schema": "^9.0.9",
"graphql": "16.6.0",
"graphql-tag": "^2.12.6",
"next": "latest",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "^18.0.0",
"@types/react": "^18.0.14",
"@types/react-dom": "^18.0.5",
"typescript": "^4.7.4"
}
}
Expand Up @@ -29,13 +29,14 @@ export async function getStaticProps(context) {
}

export async function getStaticPaths() {
const { users } = await queryGraphql(`
const { users } = (await queryGraphql(`
query {
users {
username
}
}
`)
`)) as { users: { username: string }[] }

return {
paths: users.map(({ username }) => ({
params: { username },
Expand Down
@@ -1,4 +1,7 @@
import { ApolloServer, gql, makeExecutableSchema } from 'apollo-server-micro'
import { ApolloServer } from '@apollo/server'
import { startServerAndCreateNextHandler } from '@as-integrations/next'
import { makeExecutableSchema } from '@graphql-tools/schema'
import { gql } from 'graphql-tag'

const typeDefs = gql`
type Query {
Expand All @@ -10,6 +13,7 @@ const typeDefs = gql`
username: String
}
`

const users = [
{ name: 'Leeroy Jenkins', username: 'leeroy' },
{ name: 'Foo Bar', username: 'foobar' },
Expand All @@ -28,12 +32,8 @@ const resolvers = {

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

export const config = {
api: {
bodyParser: false,
},
}

export default new ApolloServer({ schema }).createHandler({
path: '/api/graphql',
const server = new ApolloServer({
schema,
})

export default startServerAndCreateNextHandler(server)
20 changes: 20 additions & 0 deletions examples/api-routes-apollo-server/tsconfig.json
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}