What is @n1ru4l/graphql-live-query?
@n1ru4l/graphql-live-query is a package that enables live queries in GraphQL. It allows clients to receive real-time updates when the result of a query changes, providing a more dynamic and interactive experience.
What are @n1ru4l/graphql-live-query's main functionalities?
Live Queries
This feature allows you to set up live queries in your GraphQL server. The code sample demonstrates how to integrate live queries using the @n1ru4l/graphql-live-query package.
const { execute, subscribe } = require('@n1ru4l/graphql-live-query');
const { makeExecutableSchema } = require('@graphql-tools/schema');
const { useLiveQuery } = require('@n1ru4l/graphql-live-query');
const typeDefs = `
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
const liveQueryStore = new LiveQueryStore();
const executeWithLiveQueries = useLiveQuery({
execute,
subscribe,
liveQueryStore,
});
const result = await executeWithLiveQueries({
schema,
document: parse('{ hello }'),
contextValue: {},
variableValues: {},
operationName: null,
});
console.log(result);
Live Query Store
The Live Query Store is used to manage and store live queries. The code sample shows how to create a Live Query Store, add a live query to it, and notify subscribers of changes.
const { LiveQueryStore } = require('@n1ru4l/graphql-live-query');
const liveQueryStore = new LiveQueryStore();
// Add a live query to the store
const queryId = liveQueryStore.add({
document: parse('{ hello }'),
variables: {},
contextValue: {},
rootValue: {},
operationName: null,
});
// Notify subscribers of changes
liveQueryStore.invalidate(queryId);
Other packages similar to @n1ru4l/graphql-live-query
graphql-subscriptions
graphql-subscriptions is a package that provides a way to implement GraphQL subscriptions using PubSub. It allows clients to subscribe to specific events and receive real-time updates. Unlike @n1ru4l/graphql-live-query, which focuses on live queries, graphql-subscriptions is more event-driven and requires explicit subscription to events.
apollo-server
apollo-server is a popular GraphQL server implementation that supports subscriptions out of the box. It uses WebSocket for real-time communication and can be integrated with various PubSub mechanisms. While it provides a comprehensive solution for GraphQL servers, including subscriptions, it does not specifically focus on live queries like @n1ru4l/graphql-live-query.
@n1ru4l/graphql-live-query
Primitives for adding GraphQL live query operation support to any GraphQL server.
For a usage of those utility functions check out InMemoryLiveQueryStore
(https://github.com/n1ru4l/graphql-live-queries/tree/main/packages/in-memory-live-query-store/src/InMemoryLiveQueryStore.ts).
Install Instructions
yarn add -E @n1ru4l/graphql-live-query
API
GraphQLLiveDirective
Add the @live
directive to your schema.
import { GraphQLSchema, specifiedDirectives } from "graphql";
import { GraphQLLiveDirective } from "@n1ru4l/graphql-live-query";
import { query, mutation, subscription } from "./schema";
const schema = new GraphQLSchema({
query,
mutation,
subscription,
directives: [
GraphQLLiveDirective,
...specifiedDirectives,
],
});
Note: If you are using a SDL first approach for defining your schema (such as advocated by makeExecutableSchema
) you must add the directly to your type-definitions. In order to be as up to date as possible we recommend using graphql-tools/utils
astFromDirective
together with print
exported from graphql
for generating the SDL from GraphQLLiveDirective
.
Example (on CodeSandbox
):
import { makeExecutableSchema } from "@graphql-tools/schema";
import { astFromDirective } from "@graphql-tools/utils";
import { GraphQLLiveDirective } from "@n1ru4l/graphql-live-query";
import { print, GraphQLSchema } from "graphql";
const typeDefinitions = `
type Query {
ping: Boolean
}
`;
const resolvers = {
Query: {
ping: () => true
}
};
const liveDirectiveTypeDefs = print(
astFromDirective(GraphQLLiveDirective)
);
export const schema = makeExecutableSchema({
typeDefs: [typeDefinitions, liveDirectiveTypeDefs],
resolvers
});
isLiveQueryOperationDefinitionNode
Determine whether a DefinitionNode
is a LiveQueryOperationDefinitionNode
.
import { parse, getOperationAST } from "graphql";
import { isLiveQueryOperationDefinitionNode } from "@n1ru4l/graphql-live-query";
const liveQueryOperationDefinitionNode = getOperationAST(
parse( `
query @live {
me {
id
login
}
}
`)
);
isLiveQueryOperationDefinitionNode(liveQueryOperationDefinitionNode);
const queryOperationDefinitionNode = getOperationAST(
parse( `
query {
me {
id
login
}
}
`)
);
isLiveQueryOperationDefinitionNode(queryOperationDefinitionNode);
const conditionalLiveQueryDefinitionNode = getOperationAST(
parse( `
query($isClient: Boolean = false) @live(if: $isClient) {
me {
id
login
}
}
`)
);
isLiveQueryOperationDefinitionNode(conditionalLiveQueryDefinitionNode);
isLiveQueryOperationDefinitionNode(
conditionalLiveQueryDefinitionNode,
{
isClient: false,
}
);
isLiveQueryOperationDefinitionNode(
conditionalLiveQueryDefinitionNode,
{
isClient: true,
}
);
NoLiveMixedWithDeferStreamRule
Validation rule for raising a GraphQLError for a operation that use @live
mixed with @defer
and @stream
.
import { parse, validate, specifiedRules } from "graphql";
import { NoLiveMixedWithDeferStreamRule } from "@n1ru4l/graphql-live-query";
import schema from "./schema";
const document = parse( `
query @live {
users @stream {
id
login
}
}
`);
const [error] = validate(schema, document, [
...specifiedRules,
NoLiveMixedWithDeferStreamRule,
]);
console.log(error);