A layer for serving a GraphQL schema via a socket.io server. Supports Queries, Mutations, Subscriptions and Live Queries.
Note: Use @n1ru4l/socket-io-graphql-client
for executing operations against the server.
For a full setup check out the todo-example-server.
yarn add -E @n1ru4l/socket-io-graphql-server
Registers the Socket.io GraphQL layer.
import { registerSocketIOGraphQLServer } from "@n1ru4l/socket-io-graphql-server";
import { Server as IOServer } from "socket.io";
const socketServer = new IOServer();
registerSocketIOGraphQLServer({
socketServer,
/* getParameter is invoked for each incoming operation and provides all values required for execution. */
getParameter: ({
/* Socket.io instance of the client that executes the operation */ socket,
}) => ({
/* The parameters used for the operation execution. */
graphQLExecutionParameter: {
/* GraphQL schema used for exection (required) */
schema,
/* root value for execution (optional) */
rootValue: {},
/* context value for execution (optional) */
contextValue: {
socket,
},
},
}),
});
You must also install @n1ru4l/in-memory-live-query-store
(or implement your own live query execute function).
yarn add -E @n1ru4l/in-memory-live-query-store
import { Server as IOServer } from "socket.io";
import { InMemoryLiveQueryStore } from "@n1ru4l/in-memory-live-query-store";
import { NoLiveMixedWithDeferStreamRule } from "@n1ru4l/graphql-live-query";
import { validate, specifiedRules } from "graphql";
const socketServer = new IOServer()
// liveQueryStore is fully optional
// you can even use your own implementation
const liveQueryStore = new InMemoryLiveQueryStore();
const validationRules = [...specifiedRules, NoLiveMixedWithDeferStreamRule];
registerSocketIOGraphQLServer({
socketServer,
/* getParameter is invoked for each operation. */
getParameter: ({ socket }) => ({
execute: liveQueryStore.execute,
/* Overwrite validation rules. */
validationRules,
/* The parameters used for the operation execution. */
graphQLExecutionParameter: {
schema,
rootValue:,
contextValue: {
socket,
liveQueryStore,
},
},
}),
});
Sometimes you only want to permit a socket executing stuff after authentication.
import { Server as IOServer } from "socket.io";
const socketServer = new IOServer();
const graphQLServer = registerSocketIOGraphQLServer({
socketServer,
getParameter: () => ({
graphQLExecutionParameter: {
schema,
rootValue,
contextValue: {
liveQueryStore,
},
},
}),
// do not automatically register each socket for operation execution
isLazy: true,
});
socketServer.on("connect", (socket) => {
socket.on("auth", (message) => {
if (checkAuth(message)) {
// now socket is allowed to execute GraphQL operations.
graphQLServer.registerSocket(socket);
}
});
});
import { Server as IOServer } from "socket.io";
import { InMemoryLiveQueryStore } from "@n1ru4l/graphql-live-query-store";
const persistedOperations = {
"1": "query { ping }"
"2": "mutation { ping }"
}
const socketServer = new IOServer();
const graphqlServer = registerSocketIOGraphQLServer({
socketServer,
getParameter: ({ socket, graphQLPayload }) => ({
/* The paramaters used for the operation execution. */
graphQLExecutionParameter: {
schema,
rootValue:,
contextValue: {
socket,
},
// client source is just the id instead of a full document.
// we map the id to the actual document.
source: persistedOperations[graphQLPayload.source]
},
}),
});
const server = registerSocketIOGraphQLServer({
socketServer,
getParameter: ({ socket }) => ({
graphQLExecutionParameter: {
schema,
rootValue,
contextValue: {
liveQueryStore,
},
},
}),
});
server.destroy();