@chillicream/nitro-express-middleware
Version:
Express middleware for Nitro GraphQL IDE
313 lines (239 loc) • 6.61 kB
Markdown
# Nitro Express Middleware
_Express middleware for Nitro GraphQL IDE_
## Description
This middleware allows to setup _Nitro GraphQL IDE_ for your GraphQL server.
You can use a **cdn** hosted version of the app or a **self** hosted version using the ad hoc package.
## Installation
Install this package and the required `peerDependencies` in your project:
```sh
npm install @chillicream/nitro-express-middleware --save-dev
# or
yarn add @chillicream/nitro-express-middleware --dev
# or
pnpm add @chillicream/nitro-express-middleware --save-dev
```
**Note**: `@chillicream/nitro-embedded` is optional and only needed if you prefer to **self** host the app.
## Usage
Add the middleware to your app.
```javascript
import express from "express";
import nitroMiddleware from "@chillicream/nitro-express-middleware";
// ...
const app = express();
app.use(
"/graphql",
// for `cdn` hosted version
nitroMiddleware({ mode: "cdn" })
// for `embedded` version
// nitroMiddleware({ mode: "embedded" }),
// place here your graphql middleware and others
);
app.listen(3000, () => {
console.log(`GraphQL on http://localhost:3000/graphql`);
});
```
### Extended configuration
- To pin a specific version instead of using "latest":
```javascript
nitroMiddleware({
mode: "cdn",
target: { version: "3.0.0" },
});
```
- To use your own infrastructure:
```javascript
nitroMiddleware({
mode: "cdn",
target: "https://mycompany.com/nitro",
});
```
### Custom options
- To pass `options` supported by _Nitro GraphQL IDE_:
```javascript
nitroMiddleware({
mode: "cdn",
options: {
title: "nitro",
},
});
```
## Recipes
<details id="graphql-http">
<summary><a href="#graphql-http"><sub><sup>🔗</sup></sub></a> With <a href="https://github.com/enisdenjo/graphql-http">graphql-http</a></summary>
<hr>
```javascript
import express from "express";
import { createHandler } from "graphql-http";
import { GraphQLObjectType, GraphQLSchema, GraphQLString } from "graphql";
import nitroMiddleware from "@chillicream/nitro-express-middleware";
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: "Query",
fields: {
greeting: {
type: GraphQLString,
resolve(_parent, _args) {
return "Hello, World!";
},
},
},
}),
});
const app = express();
const handler = createHandler({ schema });
app.use(
"/graphql",
// for `cdn` hosted version
nitroMiddleware({ mode: "cdn" }),
// for `embedded` version
// nitroMiddleware({ mode: "embedded" }),
async (req, res) => {
try {
const [body, init] = await handler({
url: req.url,
method: req.method,
headers: req.headers,
body: () =>
new Promise((resolve) => {
let body = "";
req.on("data", (chunk) => (body += chunk));
req.on("end", () => resolve(body));
}),
raw: req,
});
res.writeHead(init.status, init.statusText, init.headers).end(body);
} catch (err) {
res.writeHead(500).end(err.message);
}
}
);
app.listen(3000, () => {
console.log(`GraphQL on http://localhost:3000/graphql`);
});
```
<hr>
</details>
<details id="graphql-yoga">
<summary><a href="#graphql-yoga"><sub><sup>🔗</sup></sub></a> With <a href="https://the-guild.dev/graphql/yoga-server">graphql-yoga</a></summary>
<hr>
```javascript
import express from "express";
import { createYoga, createSchema } from "graphql-yoga";
import nitroMiddleware from "@chillicream/nitro-express-middleware";
const graphQLServer = createYoga({
schema: createSchema({
typeDefs: /* GraphQL */ `
type Query {
greeting: String
}
`,
resolvers: {
Query: {
greeting: () => "Hello, World!",
},
},
}),
logging: false,
});
const app = express();
app.use(
"/graphql",
// for `cdn` hosted version
nitroMiddleware({ mode: "cdn" }),
// for `embedded` version
// nitroMiddleware({ mode: "embedded" }),
graphQLServer
);
app.listen(3000, () => {
console.log(`GraphQL on http://localhost:3000/graphql`);
});
```
<hr>
</details>
<details id="express-graphql">
<summary><a href="#express-graphql"><sub><sup>🔗</sup></sub></a> With <a href="https://github.com/graphql/express-graphql">express-graphql</a></summary>
<hr>
```javascript
import express from "express";
import { graphqlHTTP } from "express-graphql";
import { GraphQLObjectType, GraphQLSchema, GraphQLString } from "graphql";
import nitroMiddleware from "@chillicream/nitro-express-middleware";
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: "Query",
fields: {
greeting: {
type: GraphQLString,
resolve(_parent, _args) {
return "Hello, World!";
},
},
},
}),
});
const app = express();
app.use(
"/graphql",
// for `cdn` hosted version
nitroMiddleware({ mode: "cdn" }),
// for `embedded` version
// nitroMiddleware({ mode: "embedded" }),
graphqlHTTP({
schema,
graphiql: false,
})
);
app.listen(3000, () => {
console.log(`GraphQL on http://localhost:3000/graphql`);
});
```
<hr>
</details>
<details id="apollo-server">
<summary><a href="#apollo-server"><sub><sup>🔗</sup></sub></a> With <a href="https://www.apollographql.com/docs/apollo-server/">apollo-server-</a></summary>
<hr>
```javascript
import { ApolloServer } from "@apollo/server";
import { expressMiddleware } from "@apollo/server/express4";
import { ApolloServerPluginDrainHttpServer } from "@apollo/server/plugin/drainHttpServer";
import express from "express";
import http from "http";
import cors from "cors";
import bodyParser from "body-parser";
import nitroMiddleware from "@chillicream/nitro-express-middleware";
const typeDefs = `#graphql
type Query {
greeting: String
}
`;
const resolvers = {
Query: {
greeting: () => "Hello, World!",
},
};
const app = express();
const httpServer = http.createServer(app);
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});
await server.start();
app.use(
"/graphql",
// for `cdn` hosted version
nitroMiddleware({ mode: "cdn" }),
// for `embedded` version
// nitroMiddleware({ mode: "embedded" }),
cors(),
bodyParser.json(),
expressMiddleware(server, {
context: async ({ req }) => ({ token: req.headers.token }),
})
);
httpServer.listen({ port: 3000 }, () => {
console.log(`GraphQL on http://localhost:3000/graphql`);
});
```
<hr>
</details>