Skip to content

Commit cf0158c

Browse files
charlypolyleerobijjk
authored
feat(examples): build a GraphQL Gateway with GraphQL Mesh and Next.js API routes (#36439)
* feat(examples): GraphQL Mesh Gateway example * doc(examples/with-graphql-gateway): README * fix(examples/with-graphql-gateway): ignore `.mesh/` * Apply suggestions from code review * lint-fix Co-authored-by: Lee Robinson <[email protected]> Co-authored-by: JJ Kasper <[email protected]>
1 parent 1b4e2cc commit cf0158c

File tree

14 files changed

+408
-0
lines changed

14 files changed

+408
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
*.pem
21+
22+
# debug
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
.pnpm-debug.log*
27+
28+
# local env files
29+
.env*.local
30+
31+
# vercel
32+
.vercel
33+
34+
# typescript
35+
*.tsbuildinfo
36+
37+
.mesh/
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
sources:
2+
- name: PetStore
3+
handler:
4+
newOpenapi:
5+
baseUrl: https://petstore.swagger.io/v2/
6+
oasFilePath: https://petstore.swagger.io/v2/swagger.json
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# GraphQL Gateway using GraphQL Mesh and Next.js API routes
2+
3+
This is a simple set up for Next.js using [GraphQL Mesh](https://www.graphql-mesh.com/docs/introduction) to build a GraphQL Gateway based on a REST API.
4+
5+
GraphQL Mesh is a framework that allows to build GraphQL Gateway server, based on one or multiple source APIs (REST, SOAP, gRPC, GraphQL or Databases).
6+
7+
```mermaid
8+
graph TD;
9+
subgraph AA [" "]
10+
A[Mobile app];
11+
B[Web app];
12+
C[Node.js client];
13+
end
14+
subgraph BB [" "]
15+
E[REST API];
16+
F[GraphQL API];
17+
G[SOAP API];
18+
end
19+
Z[GraphQL Gateway API on a Next.js API route];
20+
A & B & C --> Z;
21+
Z --> E & F & G;
22+
```
23+
24+
Configuring GraphQL Mesh only requires installing the required packages and providing a `.meshrc.yaml` configuration file.
25+
26+
This project translate the PetStore REST API (https://petstore.swagger.io/) to a GraphQL API by simply providing the following configuration:
27+
28+
_[`.meshrc.yaml`](./.meshrc.yaml)_
29+
30+
```yaml
31+
sources:
32+
- name: PetStore
33+
handler:
34+
newOpenapi:
35+
baseUrl: https://petstore.swagger.io/v2/
36+
oasFilePath: https://petstore.swagger.io/v2/swagger.json
37+
```
38+
39+
More information on GraphQL Mesh configuration and concepts [are available in our documentation](https://www.graphql-mesh.com/docs/getting-started/overview).
40+
41+
---
42+
43+
## Deploy your own
44+
45+
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
46+
47+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-graphql-gateway&project-name=with-graphql-gateway&repository-name=with-graphql-gateway&env=NEO4J_URI,NEO4J_USER,NEO4J_PASSWORD&envDescription=Required%20to%20connect%20the%20app%20with%20a%20Neo4j%20database&envLink=https://github.com/vercel/next.js/tree/canary/examples/with-graphql-gateway%23step-3-set-up-environment-variables)
48+
49+
---
50+
51+
## How to use
52+
53+
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
54+
55+
```bash
56+
npx create-next-app --example with-graphql-gateway with-graphql-gateway-app
57+
# or
58+
yarn create next-app --example with-graphql-gateway with-graphql-gateway-app
59+
# or
60+
pnpm create next-app -- --example with-graphql-gateway with-graphql-gateway-app
61+
```
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/image-types/global" />
3+
4+
// NOTE: This file should not be edited
5+
// see https://nextjs.org/docs/basic-features/typescript for more information.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/** @type {import('next').NextConfig} */
2+
const nextConfig = {
3+
reactStrictMode: true,
4+
}
5+
6+
module.exports = nextConfig
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"prestart": "yarn build:mesh",
5+
"start": "next dev",
6+
"prebuild": "yarn build:mesh",
7+
"build": "next build",
8+
"start:prod": "next start",
9+
"build:mesh": "mesh build"
10+
},
11+
"dependencies": {
12+
"@graphql-mesh/cli": "0.68.1",
13+
"@graphql-mesh/config": "0.35.1",
14+
"@graphql-mesh/new-openapi": "0.4.10",
15+
"@graphql-mesh/runtime": "0.34.1",
16+
"@graphql-yoga/node": "latest",
17+
"graphql": "16.3.0",
18+
"next": "latest",
19+
"react": "18.0.0",
20+
"react-dom": "18.0.0"
21+
},
22+
"devDependencies": {
23+
"@types/node": "17.0.24",
24+
"@types/react": "18.0.5",
25+
"@types/react-dom": "18.0.1",
26+
"typescript": "4.6.3"
27+
}
28+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import '../styles/globals.css'
2+
import type { AppProps } from 'next/app'
3+
4+
function MyApp({ Component, pageProps }: AppProps) {
5+
return <Component {...pageProps} />
6+
}
7+
8+
export default MyApp
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2+
import type { NextApiRequest, NextApiResponse } from 'next'
3+
import { createServer } from '@graphql-yoga/node'
4+
5+
import { getBuiltMesh } from '../../.mesh'
6+
7+
async function buildServer() {
8+
// retrieve the mesh instance (with configured Envelop plugins)
9+
const mesh = await getBuiltMesh()
10+
// pass the Mesh instance to Yoga and configure GraphiQL
11+
const server = createServer({
12+
plugins: mesh.plugins,
13+
graphiql: {
14+
endpoint: '/api/graphql',
15+
title: 'GraphQL Gateway',
16+
},
17+
})
18+
19+
return server
20+
}
21+
22+
const server$ = buildServer()
23+
24+
export default async function apiHandler(
25+
req: NextApiRequest,
26+
res: NextApiResponse
27+
) {
28+
return (await server$).requestListener(req, res)
29+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import type { NextPage } from 'next'
2+
import Head from 'next/head'
3+
import Image from 'next/image'
4+
import styles from '../styles/Home.module.css'
5+
6+
const Home: NextPage = () => {
7+
return (
8+
<div className={styles.container}>
9+
<Head>
10+
<title>Create Next App</title>
11+
<meta name="description" content="Generated by create next app" />
12+
<link rel="icon" href="/favicon.ico" />
13+
</Head>
14+
15+
<main className={styles.main}>
16+
<h1 className={styles.title}>
17+
Welcome to <a href="https://nextjs.org">Next.js!</a>
18+
</h1>
19+
20+
<p className={styles.description}>
21+
Get started by editing{' '}
22+
<code className={styles.code}>pages/index.tsx</code>
23+
</p>
24+
25+
<div className={styles.grid}>
26+
<a href="https://nextjs.org/docs" className={styles.card}>
27+
<h2>Documentation &rarr;</h2>
28+
<p>Find in-depth information about Next.js features and API.</p>
29+
</a>
30+
31+
<a href="https://nextjs.org/learn" className={styles.card}>
32+
<h2>Learn &rarr;</h2>
33+
<p>Learn about Next.js in an interactive course with quizzes!</p>
34+
</a>
35+
36+
<a
37+
href="https://github.com/vercel/next.js/tree/canary/examples"
38+
className={styles.card}
39+
>
40+
<h2>Examples &rarr;</h2>
41+
<p>Discover and deploy boilerplate example Next.js projects.</p>
42+
</a>
43+
44+
<a
45+
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
46+
className={styles.card}
47+
>
48+
<h2>Deploy &rarr;</h2>
49+
<p>
50+
Instantly deploy your Next.js site to a public URL with Vercel.
51+
</p>
52+
</a>
53+
</div>
54+
</main>
55+
56+
<footer className={styles.footer}>
57+
<a
58+
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
59+
target="_blank"
60+
rel="noopener noreferrer"
61+
>
62+
Powered by{' '}
63+
<span className={styles.logo}>
64+
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
65+
</span>
66+
</a>
67+
</footer>
68+
</div>
69+
)
70+
}
71+
72+
export default Home
25.3 KB
Binary file not shown.

0 commit comments

Comments
 (0)