Skip to content
This repository was archived by the owner on Mar 20, 2023. It is now read-only.

Commit 6f88898

Browse files
junminstoragejliu670junmin_liu
authored
Subscription support for GraphiQL (#687)
* FEAT: add subscription support * Added http-test for subscription scenario * add sample implementation with subscription support * move subscription test case within graphiql section * fixed linter error by adding null check Co-authored-by: jliu670 <[email protected]> Co-authored-by: junmin_liu <[email protected]>
1 parent ad54975 commit 6f88898

File tree

5 files changed

+306
-1
lines changed

5 files changed

+306
-1
lines changed

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,54 @@ app.get(
6868
app.listen(4000);
6969
```
7070

71+
## Setup with Subscription Support
72+
73+
```js
74+
const express = require('express');
75+
const { graphqlHTTP } = require('express-graphql');
76+
77+
const typeDefs = require('./schema');
78+
const resolvers = require('./resolvers');
79+
const { makeExecutableSchema } = require('graphql-tools');
80+
const schema = makeExecutableSchema({
81+
typeDefs: typeDefs,
82+
resolvers: resolvers,
83+
});
84+
85+
const { execute, subscribe } = require('graphql');
86+
const { createServer } = require('http');
87+
const { SubscriptionServer } = require('subscriptions-transport-ws');
88+
89+
const PORT = 4000;
90+
91+
var app = express();
92+
93+
app.use(
94+
'/graphql',
95+
graphqlHTTP({
96+
schema: schema,
97+
graphiql: { subscriptionEndpoint: `ws://localhost:${PORT}/subscriptions` },
98+
}),
99+
);
100+
101+
const ws = createServer(app);
102+
103+
ws.listen(PORT, () => {
104+
// Set up the WebSocket for handling GraphQL subscriptions.
105+
new SubscriptionServer(
106+
{
107+
execute,
108+
subscribe,
109+
schema,
110+
},
111+
{
112+
server: ws,
113+
path: '/subscriptions',
114+
},
115+
);
116+
});
117+
```
118+
71119
## Options
72120

73121
The `graphqlHTTP` function accepts the following options:
@@ -88,6 +136,8 @@ The `graphqlHTTP` function accepts the following options:
88136
- **`headerEditorEnabled`**: An optional boolean which enables the header editor when true.
89137
Defaults to false.
90138

139+
- **`subscriptionEndpoint`**: An optional GraphQL string contains the WebSocket server url for subscription.
140+
91141
- **`rootValue`**: A value to pass as the `rootValue` to the `graphql()`
92142
function from [`GraphQL.js/src/execute.js`](https://github.com/graphql/graphql-js/blob/master/src/execution/execute.js#L119).
93143

package-lock.json

Lines changed: 191 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
"eslint-plugin-node": "11.1.0",
8585
"express": "4.17.1",
8686
"graphiql": "1.0.6",
87+
"graphiql-subscriptions-fetcher": "0.0.2",
8788
"graphql": "15.4.0",
8889
"mocha": "8.2.1",
8990
"multer": "1.4.2",
@@ -94,6 +95,7 @@
9495
"react-dom": "16.14.0",
9596
"restify": "8.5.1",
9697
"sinon": "9.2.1",
98+
"subscriptions-transport-ws": "0.5.4",
9799
"supertest": "6.0.1",
98100
"ts-node": "9.0.0",
99101
"typescript": "4.1.2",

src/__tests__/http-test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1988,6 +1988,33 @@ function runTests(server: Server) {
19881988
expect(response.type).to.equal('application/json');
19891989
expect(response.text).to.equal('{"data":{"test":"Hello World"}}');
19901990
});
1991+
1992+
it('contains subscriptionEndpoint within GraphiQL', async () => {
1993+
const app = server();
1994+
1995+
app.get(
1996+
urlString(),
1997+
graphqlHTTP({
1998+
schema: TestSchema,
1999+
graphiql: { subscriptionEndpoint: 'ws://localhost' },
2000+
}),
2001+
);
2002+
2003+
const response = await app
2004+
.request()
2005+
.get(urlString())
2006+
.set('Accept', 'text/html');
2007+
2008+
expect(response.status).to.equal(200);
2009+
expect(response.type).to.equal('text/html');
2010+
// should contain the function to make fetcher for subscription or non-subscription
2011+
expect(response.text).to.include('makeFetcher');
2012+
// should contain subscriptions-transport-ws browser client
2013+
expect(response.text).to.include('SubscriptionsTransportWs');
2014+
2015+
// should contain the subscriptionEndpoint url
2016+
expect(response.text).to.include('ws:\\/\\/localhost');
2017+
});
19912018
});
19922019

19932020
describe('Custom validate function', () => {

0 commit comments

Comments
 (0)