---
description:
  Use GraphQL Mesh Live Queries to update GraphQL operation results automatically. Learn how to
  configure the Live Query plugin with examples and a code sandbox demo.
---

import { Callout } from '@theguild/components'

# Live Queries

GraphQL Live Query implementation from [Laurin Quast](https://github.com/n1ru4l) can be used in
GraphQL Mesh with a few additions in the configuration.

```sh npm2yarn
npm i @graphql-mesh/plugin-live-query
```

### Basic Usage

You have a `Query` root field that returns all `Todo` entities from your data source like below.

```graphql
query getTodos {
  todos {
    id
    content
  }
}
```

And you want to update this operation result automatically without manual refresh when
`Mutation.addTodo` is called.

You only need to add the following to your existing configuration.

```yaml filename=".meshrc.yaml"
additionalTypeDefs: |
  directive @live on QUERY
plugins:
  - liveQuery:
      invalidations:
        - field: Mutation.addTodo
          invalidate:
            - Query.todos
```

Then you can send a live query with `@live` directive.

```graphql /@live/
query getTodos @live {
  todos {
    id
    content
  }
}
```

This will start a real-time connection between the server and your client. The response of `todos`
will get updated whenever `addTodo` is called.

### ID Based Invalidation

Let's say you have the following query that returns a specific `Todo` entity based on `id` field;

```graphql
query getTodo($id: ID!) {
  todo(id: $id) {
    id
    content
  }
}
```

If you update this entity with `editTodo` mutation field on your backend, then you want to
invalidate this entity specifically instead of validating all `todo` queries;

```yaml filename=".meshrc.yaml"
invalidations:
  - field: Mutation.editTodo
    invalidate:
      - Todo:{args.id}
```

In a case where the field resolver resolves null but might resolve to an object type later, e.g.,
because the visibility got update the field that uses a specific id argument can be invalidated in
the following way:

```yaml filename=".meshrc.yaml"
invalidations:
  - field: Mutation.editTodo
    invalidate:
      - Query.todo(id:"{args.id}")
```

### Polling Based Invalidation

You can also invalidate queries in a polling interval by specifying the schema coordinate of the
query to be polled.

```yaml filename=".meshrc.yaml"
plugins:
  - liveQuery:
      invalidations:
        - pollingInterval: 10000 # Polling interval in milliseconds
          invalidate:
            - Query.products
```

### Programmatic Usage

`liveQueryStore` is available in GraphQL Context, so you can access it in resolvers composition
functions that wrap existing resolvers or additional resolvers;

See [Resolvers Composition](/docs/transforms/resolvers-composition)

```yaml filename=".meshrc.yaml"
transforms:
  - resolversComposition:
      - resolver: Mutation.editTodo
        composer: invalidate-todo#invalidateTodo
```

And in this code file;

```ts filename="invalidate-todo.ts"
module.exports = {
  invalidateTodo: next => async (root, args, context, info) => {
    const result = await next(root, args, context, info)
    context.liveQueryStore.invalidate(`Todo:${args.id}`)
    return result
  }
}
```

## Config API Reference

import API from '../../../generated-markdown/ResponseCacheConfig.generated.md'

<API />

## CodeSandBox Example

<Callout>
  You can learn more about [GraphQL Live Query](https://github.com/n1ru4l/graphql-live-query) in its
  documentation. You can check out our example that uses live queries
</Callout>

<iframe
  src="https://codesandbox.io/embed/github/ardatan/graphql-mesh/tree/master/examples/json-schema-subscriptions?fontsize=14&hidenavigation=1&theme=dark&module=%2F.meshrc.yml"
  className="mt-6 w-full h-[500px] rounded-md"
  title="json-schema-subscriptions"
  allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
  sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
/>
