Skip to main content

Introduction

The NestJS Query data provider enables you to build Refine applications with NestJS Query, a GraphQL library for NestJS. It provides full support for CRUD operations, filtering, sorting, and real-time subscriptions.

Installation

Install the NestJS Query data provider and required dependencies:
npm install @refinedev/nestjs-query graphql-tag graphql-ws

Setup

1

Create GraphQL client

Create a GraphQL client with your NestJS Query API URL:
import { GraphQLClient } from "@refinedev/nestjs-query";

const client = new GraphQLClient("https://api.example.com/graphql");
2

Configure data provider

Configure the Refine app with the NestJS Query data provider:
import { Refine } from "@refinedev/core";
import dataProvider, { GraphQLClient } from "@refinedev/nestjs-query";

const client = new GraphQLClient("https://api.example.com/graphql");

const App = () => {
  return (
    <Refine
      dataProvider={dataProvider(client)}
    >
      {/* Your app content */}
    </Refine>
  );
};

Basic Usage

Get List

Fetch a list of records with NestJS Query conventions:
import { useList } from "@refinedev/core";
import gql from "graphql-tag";

const POSTS_QUERY = gql`
  query GetPosts(
    $paging: OffsetPaging!
    $filter: PostFilter
    $sorting: [PostSort!]
  ) {
    posts(paging: $paging, filter: $filter, sorting: $sorting) {
      nodes {
        id
        title
        content
        createdAt
      }
      totalCount
    }
  }
`;

const { data } = useList({
  resource: "posts",
  pagination: {
    current: 1,
    pageSize: 10,
  },
  meta: {
    gqlQuery: POSTS_QUERY,
  },
});

Get One

Fetch a single record by ID:
import { useOne } from "@refinedev/core";
import gql from "graphql-tag";

const POST_QUERY = gql`
  query GetPost($id: ID!) {
    post(id: $id) {
      id
      title
      content
      createdAt
      author {
        id
        name
      }
    }
  }
`;

const { data } = useOne({
  resource: "posts",
  id: "1",
  meta: {
    gqlQuery: POST_QUERY,
  },
});

Create

Create a new record:
import { useCreate } from "@refinedev/core";
import gql from "graphql-tag";

const CREATE_POST_MUTATION = gql`
  mutation CreatePost($input: CreatePostInput!) {
    createOnePost(input: { post: $input }) {
      id
      title
      content
    }
  }
`;

const { mutate } = useCreate();

const handleSubmit = (values) => {
  mutate({
    resource: "posts",
    values,
    meta: {
      gqlMutation: CREATE_POST_MUTATION,
    },
  });
};

Update

Update an existing record:
import { useUpdate } from "@refinedev/core";
import gql from "graphql-tag";

const UPDATE_POST_MUTATION = gql`
  mutation UpdatePost($id: ID!, $input: UpdatePostInput!) {
    updateOnePost(input: { id: $id, update: $input }) {
      id
      title
      content
    }
  }
`;

const { mutate } = useUpdate();

const handleUpdate = (id, values) => {
  mutate({
    resource: "posts",
    id,
    values,
    meta: {
      gqlMutation: UPDATE_POST_MUTATION,
    },
  });
};

Delete

Delete a record:
import { useDelete } from "@refinedev/core";
import gql from "graphql-tag";

const DELETE_POST_MUTATION = gql`
  mutation DeletePost($id: ID!) {
    deleteOnePost(input: { id: $id }) {
      id
    }
  }
`;

const { mutate } = useDelete();

const handleDelete = (id) => {
  mutate({
    resource: "posts",
    id,
    meta: {
      gqlMutation: DELETE_POST_MUTATION,
    },
  });
};

Filtering

NestJS Query provides powerful filtering capabilities:
import { useList } from "@refinedev/core";
import gql from "graphql-tag";

const POSTS_QUERY = gql`
  query GetPosts($filter: PostFilter) {
    posts(filter: $filter) {
      nodes {
        id
        title
        views
      }
    }
  }
`;

const { data } = useList({
  resource: "posts",
  filters: [
    {
      field: "title",
      operator: "contains",
      value: "tutorial",
    },
    {
      field: "views",
      operator: "gte",
      value: 100,
    },
    {
      field: "status",
      operator: "in",
      value: ["published", "featured"],
    },
  ],
  meta: {
    gqlQuery: POSTS_QUERY,
  },
});

Sorting

Sort records using NestJS Query sorting:
import { useList } from "@refinedev/core";
import gql from "graphql-tag";

const POSTS_QUERY = gql`
  query GetPosts($sorting: [PostSort!]) {
    posts(sorting: $sorting) {
      nodes {
        id
        title
        createdAt
      }
    }
  }
`;

const { data } = useList({
  resource: "posts",
  sorters: [
    {
      field: "createdAt",
      order: "desc",
    },
    {
      field: "title",
      order: "asc",
    },
  ],
  meta: {
    gqlQuery: POSTS_QUERY,
  },
});

Real-time Subscriptions

Enable real-time updates using GraphQL subscriptions:
1

Create WebSocket client

import { createClient } from "graphql-ws";

const wsClient = createClient({
  url: "wss://api.example.com/graphql",
});
2

Configure live provider

import { Refine } from "@refinedev/core";
import dataProvider, {
  GraphQLClient,
  liveProvider,
} from "@refinedev/nestjs-query";
import { createClient } from "graphql-ws";

const client = new GraphQLClient("https://api.example.com/graphql");
const wsClient = createClient({ url: "wss://api.example.com/graphql" });

const App = () => {
  return (
    <Refine
      dataProvider={dataProvider(client)}
      liveProvider={liveProvider(wsClient)}
      options={{ liveMode: "auto" }}
    >
      {/* Your app content */}
    </Refine>
  );
};
3

Use subscriptions

import { useList } from "@refinedev/core";
import gql from "graphql-tag";

const POSTS_SUBSCRIPTION = gql`
  subscription OnPostsUpdate {
    updatedOnePost {
      id
      title
      updatedAt
    }
  }
`;

const PostList = () => {
  const { data } = useList({
    resource: "posts",
    meta: {
      gqlQuery: POSTS_QUERY,
      gqlSubscription: POSTS_SUBSCRIPTION,
    },
  });

  // Data automatically updates in real-time
  return <div>{/* Render posts */}</div>;
};

Relations

Query related data using NestJS Query relations:
import { useList } from "@refinedev/core";
import gql from "graphql-tag";

const POSTS_WITH_RELATIONS_QUERY = gql`
  query GetPosts {
    posts {
      nodes {
        id
        title
        content
        author {
          id
          name
          email
        }
        categories {
          nodes {
            id
            name
          }
        }
      }
    }
  }
`;

const { data } = useList({
  resource: "posts",
  meta: {
    gqlQuery: POSTS_WITH_RELATIONS_QUERY,
  },
});

Aggregations

Use NestJS Query aggregations:
import gql from "graphql-tag";
import { useCustom } from "@refinedev/core";

const POSTS_AGGREGATE_QUERY = gql`
  query GetPostsAggregate {
    postAggregate {
      count {
        id
      }
      avg {
        views
      }
      max {
        views
      }
    }
  }
`;

const { data } = useCustom({
  url: "",
  method: "get",
  meta: {
    gqlQuery: POSTS_AGGREGATE_QUERY,
  },
});

Authentication

Add authentication to your GraphQL client:
import { GraphQLClient } from "@refinedev/nestjs-query";

const client = new GraphQLClient("https://api.example.com/graphql", {
  fetch: (url, options) => {
    const token = localStorage.getItem("token");
    return fetch(url, {
      ...options,
      headers: {
        ...options?.headers,
        Authorization: token ? `Bearer ${token}` : "",
      },
    });
  },
});

Complete Example

import { Refine } from "@refinedev/core";
import dataProvider, {
  GraphQLClient,
  liveProvider,
} from "@refinedev/nestjs-query";
import { createClient } from "graphql-ws";
import routerProvider from "@refinedev/react-router";
import { BrowserRouter } from "react-router";

const API_URL = "https://api.example.com/graphql";
const WS_URL = "wss://api.example.com/graphql";

const client = new GraphQLClient(API_URL, {
  fetch: (url, options) => {
    const token = localStorage.getItem("token");
    return fetch(url, {
      ...options,
      headers: {
        ...options?.headers,
        Authorization: token ? `Bearer ${token}` : "",
      },
    });
  },
});

const wsClient = createClient({
  url: WS_URL,
  connectionParams: () => {
    const token = localStorage.getItem("token");
    return {
      headers: {
        Authorization: token ? `Bearer ${token}` : "",
      },
    };
  },
});

const App = () => {
  return (
    <BrowserRouter>
      <Refine
        dataProvider={dataProvider(client)}
        liveProvider={liveProvider(wsClient)}
        routerProvider={routerProvider}
        options={{ liveMode: "auto" }}
        resources={[
          {
            name: "posts",
            list: "/posts",
            create: "/posts/create",
            edit: "/posts/edit/:id",
            show: "/posts/show/:id",
          },
        ]}
      >
        {/* Your routes and pages */}
      </Refine>
    </BrowserRouter>
  );
};

export default App;

Filter Operators

The NestJS Query data provider supports the following filter operators:
  • eq: Equals
  • neq: Not equals
  • gt: Greater than
  • gte: Greater than or equal
  • lt: Less than
  • lte: Less than or equal
  • like: Like (SQL LIKE)
  • notLike: Not like
  • iLike: Case-insensitive like
  • notILike: Case-insensitive not like
  • in: In array
  • notIn: Not in array
  • is: Is (for booleans/null)
  • isNot: Is not

Next Steps

Data Providers Overview

Learn about other data providers

NestJS Query Docs

Explore NestJS Query features

Build docs developers (and LLMs) love