diff --git a/examples/with-typescript-graphql/.babelrc b/examples/with-typescript-graphql/.babelrc
deleted file mode 100644
index 3f90997510587..0000000000000
--- a/examples/with-typescript-graphql/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["next/babel"],
- "plugins": ["graphql-let/babel"]
-}
diff --git a/examples/with-typescript-graphql/.gitignore b/examples/with-typescript-graphql/.gitignore
index bb4ca946e5e9d..aa06bce141350 100644
--- a/examples/with-typescript-graphql/.gitignore
+++ b/examples/with-typescript-graphql/.gitignore
@@ -38,3 +38,6 @@ yarn-error.log*
*.graphql.d.ts
*.graphqls.d.ts
.cache
+
+lib/resolvers-types.ts
+lib/graphql-operations.ts
diff --git a/examples/with-typescript-graphql/.graphql-let.yml b/examples/with-typescript-graphql/.graphql-let.yml
deleted file mode 100644
index 223562044eaf6..0000000000000
--- a/examples/with-typescript-graphql/.graphql-let.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-schema: '**/*.graphqls'
-documents: '**/*.graphql'
-plugins:
- - typescript-operations
- - typescript-react-apollo
-cacheDir: .cache
diff --git a/examples/with-typescript-graphql/README.md b/examples/with-typescript-graphql/README.md
index c7f4eb4b35117..3b50d7d8fdc0f 100644
--- a/examples/with-typescript-graphql/README.md
+++ b/examples/with-typescript-graphql/README.md
@@ -2,21 +2,22 @@
One of the strengths of GraphQL is [enforcing data types on runtime](https://graphql.github.io/graphql-spec/June2018/#sec-Value-Completion). Further, TypeScript and [GraphQL Code Generator](https://graphql-code-generator.com/) (graphql-codegen) make it safer by typing data statically, so you can write truly type-protected code with rich IDE assists.
-This template extends [Apollo Server and Client Example](https://github.com/vercel/next.js/tree/canary/examples/api-routes-apollo-server-and-client#readme) by rewriting in TypeScript and integrating [graphql-let](https://github.com/piglovesyou/graphql-let#readme), which runs [TypeScript React Apollo](https://graphql-code-generator.com/docs/plugins/typescript-react-apollo) in [graphql-codegen](https://github.com/dotansimha/graphql-code-generator#readme) under the hood. It enhances the typed GraphQL use as below:
+This template gives you the best start to use GraphQL with fully typed queries (client-side) and resolvers (server-side), all this with minimum bundle size 📦
```tsx
-import { useNewsQuery } from './news.graphql'
+import { useQuery } from '@apollo/client'
+import { ViewerDocument } from 'lib/graphql-operations'
const News = () => {
- // Typed already️⚡️
- const { data: { news } } = useNewsQuery()
+ // Typed already️⚡️
+ const {
+ data: { viewer },
+ } = useQuery(ViewerDocument)
- return
{news.map(...)}
+ return {viewer.name}
}
```
-By default `**/*.graphqls` is recognized as GraphQL schema and `**/*.graphql` as GraphQL documents. If you prefer the other extensions, make sure the settings of the webpack loader in `next.config.js` and `.graphql-let.yml` are consistent.
-
## Deploy your own
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-typescript-graphql)
diff --git a/examples/with-typescript-graphql/codegen.yml b/examples/with-typescript-graphql/codegen.yml
new file mode 100644
index 0000000000000..f53d625d190eb
--- /dev/null
+++ b/examples/with-typescript-graphql/codegen.yml
@@ -0,0 +1,14 @@
+schema:
+ - 'lib/schema.ts':
+ noRequire: true
+documents: ./lib/documents/*.graphql
+generates:
+ ./lib/graphql-operations.ts:
+ plugins:
+ - typescript
+ - typescript-operations
+ - typed-document-node
+ ./lib/resolvers-types.ts:
+ plugins:
+ - typescript
+ - typescript-resolvers
diff --git a/examples/with-typescript-graphql/graphql.d.ts b/examples/with-typescript-graphql/graphql.d.ts
deleted file mode 100644
index d0cab7295668b..0000000000000
--- a/examples/with-typescript-graphql/graphql.d.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-declare module '*.graphqls' {
- import { DocumentNode } from 'graphql'
- export default typeof DocumentNode
-}
-
-declare module '*.yml'
diff --git a/examples/with-typescript-graphql/lib/apollo.ts b/examples/with-typescript-graphql/lib/apollo.ts
index 961769f6491e7..41135d3554b6d 100644
--- a/examples/with-typescript-graphql/lib/apollo.ts
+++ b/examples/with-typescript-graphql/lib/apollo.ts
@@ -5,6 +5,8 @@ import {
InMemoryCache,
NormalizedCacheObject,
} from '@apollo/client'
+import resolvers from './resolvers'
+import typeDefs from './schema'
let apolloClient: ApolloClient | undefined
@@ -16,7 +18,12 @@ export type ResolverContext = {
function createIsomorphLink(context: ResolverContext = {}) {
if (typeof window === 'undefined') {
const { SchemaLink } = require('@apollo/client/link/schema')
- const { schema } = require('./schema')
+ const { makeExecutableSchema } = require('@graphql-tools/schema')
+
+ const schema = makeExecutableSchema({
+ typeDefs,
+ resolvers,
+ })
return new SchemaLink({ schema, context })
} else {
const { HttpLink } = require('@apollo/client')
diff --git a/examples/with-typescript-graphql/lib/documents/updateName.graphql b/examples/with-typescript-graphql/lib/documents/updateName.graphql
new file mode 100644
index 0000000000000..8c457c478d057
--- /dev/null
+++ b/examples/with-typescript-graphql/lib/documents/updateName.graphql
@@ -0,0 +1,7 @@
+mutation UpdateName($name: String!) {
+ updateName(name: $name) {
+ id
+ name
+ status
+ }
+}
diff --git a/examples/with-typescript-graphql/lib/documents/viewer.graphql b/examples/with-typescript-graphql/lib/documents/viewer.graphql
new file mode 100644
index 0000000000000..5b4bc2effea0a
--- /dev/null
+++ b/examples/with-typescript-graphql/lib/documents/viewer.graphql
@@ -0,0 +1,11 @@
+query Viewer {
+ viewer {
+ ...Partial
+ status
+ }
+}
+
+fragment Partial on User {
+ id
+ name
+}
diff --git a/examples/with-typescript-graphql/lib/partial.graphql b/examples/with-typescript-graphql/lib/partial.graphql
deleted file mode 100644
index 7ad627852a9c8..0000000000000
--- a/examples/with-typescript-graphql/lib/partial.graphql
+++ /dev/null
@@ -1,4 +0,0 @@
-fragment Partial on User {
- id
- name
-}
diff --git a/examples/with-typescript-graphql/lib/resolvers.ts b/examples/with-typescript-graphql/lib/resolvers.ts
index e2125756018c6..8d2633d7ed5d6 100644
--- a/examples/with-typescript-graphql/lib/resolvers.ts
+++ b/examples/with-typescript-graphql/lib/resolvers.ts
@@ -1,5 +1,4 @@
-import { QueryResolvers, MutationResolvers } from '@graphql-types@'
-import { ResolverContext } from './apollo'
+import { Resolvers } from './resolvers-types'
const userProfile = {
id: String(1),
@@ -7,17 +6,18 @@ const userProfile = {
status: 'cached',
}
-const Query: Required> = {
- viewer(_parent, _args, _context, _info) {
- return userProfile
+const resolvers: Resolvers = {
+ Query: {
+ viewer(_parent, _args, _context, _info) {
+ return userProfile
+ },
},
-}
-
-const Mutation: Required> = {
- updateName(_parent, _args, _context, _info) {
- userProfile.name = _args.name
- return userProfile
+ Mutation: {
+ updateName(_parent, _args, _context, _info) {
+ userProfile.name = _args.name
+ return userProfile
+ },
},
}
-export default { Query, Mutation }
+export default resolvers
diff --git a/examples/with-typescript-graphql/lib/schema.ts b/examples/with-typescript-graphql/lib/schema.ts
index b7e0f139e062e..50682436e34ae 100644
--- a/examples/with-typescript-graphql/lib/schema.ts
+++ b/examples/with-typescript-graphql/lib/schema.ts
@@ -1,14 +1,17 @@
-import { join } from 'path'
-import { makeExecutableSchema } from '@graphql-tools/schema'
-import { loadFilesSync } from '@graphql-tools/load-files'
-import { mergeTypeDefs } from '@graphql-tools/merge'
-import graphQLLetConfig from '../.graphql-let.yml'
-import resolvers from './resolvers'
+const typeDefs = /* GraphQL */ `
+ type User {
+ id: ID!
+ name: String!
+ status: String!
+ }
-const loadedFiles = loadFilesSync(join(process.cwd(), graphQLLetConfig.schema))
-const typeDefs = mergeTypeDefs(loadedFiles)
+ type Query {
+ viewer: User!
+ }
-export const schema = makeExecutableSchema({
- typeDefs,
- resolvers,
-})
+ type Mutation {
+ updateName(name: String!): User!
+ }
+`
+
+export default typeDefs
diff --git a/examples/with-typescript-graphql/lib/type-defs.graphqls b/examples/with-typescript-graphql/lib/type-defs.graphqls
deleted file mode 100644
index 0b86a615950ea..0000000000000
--- a/examples/with-typescript-graphql/lib/type-defs.graphqls
+++ /dev/null
@@ -1,7 +0,0 @@
-type Query {
- viewer: User!
-}
-
-type Mutation {
- updateName(name: String!): User!
-}
diff --git a/examples/with-typescript-graphql/lib/user.graphqls b/examples/with-typescript-graphql/lib/user.graphqls
deleted file mode 100644
index b9aad32a51ef5..0000000000000
--- a/examples/with-typescript-graphql/lib/user.graphqls
+++ /dev/null
@@ -1,5 +0,0 @@
-type User {
- id: ID!
- name: String!
- status: String!
-}
diff --git a/examples/with-typescript-graphql/lib/viewer.graphql b/examples/with-typescript-graphql/lib/viewer.graphql
deleted file mode 100644
index 9be08356d8c92..0000000000000
--- a/examples/with-typescript-graphql/lib/viewer.graphql
+++ /dev/null
@@ -1,16 +0,0 @@
-# import Partial from './partial.graphql'
-
-query Viewer {
- viewer {
- ...Partial
- status
- }
-}
-
-mutation UpdateName($name: String!) {
- updateName(name: $name) {
- id
- name
- status
- }
-}
diff --git a/examples/with-typescript-graphql/next.config.js b/examples/with-typescript-graphql/next.config.js
index c6d3173c08ece..6285426ed3f78 100644
--- a/examples/with-typescript-graphql/next.config.js
+++ b/examples/with-typescript-graphql/next.config.js
@@ -1,17 +1,5 @@
module.exports = {
webpack(config, options) {
- config.module.rules.push({
- test: /\.graphql$/,
- exclude: /node_modules/,
- use: [options.defaultLoaders.babel, { loader: 'graphql-let/loader' }],
- })
-
- config.module.rules.push({
- test: /\.graphqls$/,
- exclude: /node_modules/,
- use: ['graphql-let/schema/loader'],
- })
-
config.module.rules.push({
test: /\.ya?ml$/,
type: 'json',
diff --git a/examples/with-typescript-graphql/package.json b/examples/with-typescript-graphql/package.json
index 796b595e1a704..346f287a477be 100644
--- a/examples/with-typescript-graphql/package.json
+++ b/examples/with-typescript-graphql/package.json
@@ -1,42 +1,40 @@
{
"private": true,
"scripts": {
- "codegen": "graphql-let",
+ "codegen": "graphql-codegen -r ts-node/register",
"dev": "yarn codegen && next",
"build": "yarn codegen && next build",
"test": "yarn codegen && jest",
"start": "next start"
},
"dependencies": {
- "@apollo/client": "^3.1.3",
+ "@apollo/client": "^3.5.10",
+ "graphql-tag": "^2.12.6",
"@graphql-tools/load-files": "6.0.18",
+ "@graphql-yoga/node": "^2.2.1",
"@graphql-tools/merge": "6.0.18",
"@graphql-tools/schema": "6.0.18",
- "apollo-server-micro": "^2.16.1",
- "graphql": "15.3.0",
- "next": "latest",
+ "graphql": "15.6.0",
+ "next": "^12.1.5",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
- "@graphql-codegen/cli": "^2.2.1",
- "@graphql-codegen/import-types-preset": "^2.1.6",
- "@graphql-codegen/plugin-helpers": "^2.2.0",
- "@graphql-codegen/typescript": "^2.2.4",
- "@graphql-codegen/typescript-operations": "^2.1.8",
- "@graphql-codegen/typescript-react-apollo": "^3.1.6",
- "@graphql-codegen/typescript-resolvers": "^2.3.2",
+ "@graphql-codegen/typed-document-node": "^2.2.8",
+ "@graphql-codegen/cli": "^2.6.2",
+ "@graphql-codegen/typescript": "^2.4.8",
+ "@graphql-codegen/typescript-operations": "^2.3.5",
+ "@graphql-codegen/typescript-resolvers": "^2.6.1",
+ "@types/jest": "^27.0.2",
+ "@types/mocha": "^9.0.0",
"@types/react": "^16.9.46",
"@types/react-dom": "^16.9.8",
"@types/react-test-renderer": "^17.0.1",
- "@types/jest": "^27.0.2",
- "@types/mocha": "^9.0.0",
"babel-jest": "27.2.5",
- "graphql-let": "^0.18.6",
- "graphql-tag": "2.11.0",
"jest": "^27.2.5",
"react-test-renderer": "^17.0.1",
- "typescript": "^4.5.4",
- "yaml-loader": "0.6.0"
+ "typescript": "^4.6.3",
+ "yaml-loader": "0.6.0",
+ "ts-node": "10.8.0"
}
}
diff --git a/examples/with-typescript-graphql/pages/api/graphql.ts b/examples/with-typescript-graphql/pages/api/graphql.ts
index 2018e87034117..1228b87ab5585 100644
--- a/examples/with-typescript-graphql/pages/api/graphql.ts
+++ b/examples/with-typescript-graphql/pages/api/graphql.ts
@@ -1,12 +1,16 @@
-import { ApolloServer } from 'apollo-server-micro'
-import { schema } from '../../lib/schema'
+import { createServer } from '@graphql-yoga/node'
+import gql from 'graphql-tag'
-const apolloServer = new ApolloServer({ schema })
+import resolvers from 'lib/resolvers'
+import typeDefs from 'lib/schema'
-export const config = {
- api: {
- bodyParser: false,
+const server = createServer({
+ schema: {
+ typeDefs: gql(typeDefs),
+ resolvers,
},
-}
+ endpoint: '/api/graphql',
+ // graphiql: false // uncomment to disable GraphiQL
+})
-export default apolloServer.createHandler({ path: '/api/graphql' })
+export default server
diff --git a/examples/with-typescript-graphql/pages/index.tsx b/examples/with-typescript-graphql/pages/index.tsx
index cae3acee2b8c1..f9a2de3b04aed 100644
--- a/examples/with-typescript-graphql/pages/index.tsx
+++ b/examples/with-typescript-graphql/pages/index.tsx
@@ -1,42 +1,45 @@
+import { useMutation, useQuery } from '@apollo/client'
+import { UpdateNameDocument, ViewerDocument } from 'lib/graphql-operations'
import Link from 'next/link'
import { useState } from 'react'
-import {
- ViewerQuery,
- useViewerQuery,
- useUpdateNameMutation,
- ViewerDocument,
-} from '../lib/viewer.graphql'
import { initializeApollo } from '../lib/apollo'
const Index = () => {
- const { viewer } = useViewerQuery().data!
+ const { data } = useQuery(ViewerDocument)
const [newName, setNewName] = useState('')
- const [updateNameMutation] = useUpdateNameMutation()
+ const [updateNameMutation] = useMutation(UpdateNameDocument)
const onChangeName = () => {
updateNameMutation({
variables: {
name: newName,
},
- //Follow apollo suggestion to update cache
- //https://www.apollographql.com/docs/angular/features/cache-updates/#update
+ // Follow apollo suggestion to update cache
+ // https://www.apollographql.com/docs/angular/features/cache-updates/#update
update: (cache, mutationResult) => {
const { data } = mutationResult
if (!data) return // Cancel updating name in cache if no data is returned from mutation.
// Read the data from our cache for this query.
- const { viewer } = cache.readQuery({
+ const result = cache.readQuery({
query: ViewerDocument,
- }) as ViewerQuery
- const newViewer = { ...viewer }
+ })
+ const newViewer = result ? { ...result.viewer } : null
// Add our comment from the mutation to the end.
- newViewer.name = data.updateName.name
// Write our data back to the cache.
- cache.writeQuery({ query: ViewerDocument, data: { viewer: newViewer } })
+ if (newViewer) {
+ newViewer.name = data.updateName.name
+ cache.writeQuery({
+ query: ViewerDocument,
+ data: { viewer: newViewer },
+ })
+ }
},
})
}
- return (
+ const viewer = data?.viewer
+
+ return viewer ? (
You're signed in as {viewer.name} and you're {viewer.status}. Go to the{' '}
@@ -52,7 +55,7 @@ const Index = () => {
- )
+ ) : null
}
export async function getStaticProps() {
diff --git a/examples/with-typescript-graphql/tsconfig.json b/examples/with-typescript-graphql/tsconfig.json
index 56bcf4a2f3105..938107c1923e2 100644
--- a/examples/with-typescript-graphql/tsconfig.json
+++ b/examples/with-typescript-graphql/tsconfig.json
@@ -14,11 +14,6 @@
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": ".",
- "paths": {
- "@graphql-types@": [
- "node_modules/@types/graphql-let/__generated__/__types__"
- ]
- },
"incremental": true
},
"include": ["next-env.d.ts", "graphql.d.ts", "**/*.ts", "**/*.tsx"],