Skip to main content

Introduction

The GraphQL data provider enables you to build Refine applications with GraphQL APIs. It uses urql as the GraphQL client and provides full support for queries, mutations, and subscriptions.

Installation

Install the GraphQL data provider and required dependencies:
npm install @refinedev/graphql graphql-tag

Basic Usage

1

Create GraphQL client

First, create a GraphQL client with your API URL:
import { GraphQLClient } from "@refinedev/graphql";

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

Configure data provider

Import and configure the data provider:
import { Refine } from "@refinedev/core";
import dataProvider, { GraphQLClient } from "@refinedev/graphql";

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

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

Use in your components

Now you can use Refine hooks with GraphQL queries:
import { useList } from "@refinedev/core";
import gql from "graphql-tag";

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

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

  return (
    <div>
      {data?.data.map((post) => (
        <div key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </div>
      ))}
    </div>
  );
};

Client Configuration

You can configure the GraphQL client with custom options:
import { GraphQLClient } from "@refinedev/graphql";

const client = new GraphQLClient("https://api.example.com/graphql", {
  headers: {
    Authorization: "Bearer YOUR_TOKEN",
  },
  fetch: customFetch,
  fetchOptions: {
    credentials: "include",
  },
});

Operations

Get List

Fetch a list of records with filtering and sorting:
import { useList } from "@refinedev/core";
import gql from "graphql-tag";

const POSTS_QUERY = gql`
  query GetPosts(
    $filter: PostFilter
    $sort: [PostSort!]
    $limit: Int
    $offset: Int
  ) {
    posts(filter: $filter, sort: $sort, limit: $limit, offset: $offset) {
      id
      title
      status
      createdAt
    }
    postsCount(filter: $filter)
  }
`;

const { data } = useList({
  resource: "posts",
  pagination: {
    current: 1,
    pageSize: 10,
  },
  filters: [
    {
      field: "status",
      operator: "eq",
      value: "published",
    },
  ],
  sorters: [
    {
      field: "createdAt",
      order: "desc",
    },
  ],
  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
      status
      createdAt
      author {
        id
        name
      }
    }
  }
`;

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

Get Many

Fetch multiple records by their IDs:
import { useMany } from "@refinedev/core";
import gql from "graphql-tag";

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

const { data } = useMany({
  resource: "posts",
  ids: ["1", "2", "3"],
  meta: {
    gqlQuery: POSTS_QUERY,
  },
});

Create

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

const CREATE_POST_MUTATION = gql`
  mutation CreatePost($input: CreatePostInput!) {
    createPost(input: $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!) {
    updatePost(id: $id, input: $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!) {
    deletePost(id: $id) {
      id
    }
  }
`;

const { mutate } = useDelete();

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

Live Provider

The GraphQL data provider supports real-time subscriptions using GraphQL subscriptions:
1

Install dependencies

Install the required packages for subscriptions:
npm install graphql-ws
2

Create WebSocket client

Create a WebSocket client for subscriptions:
import { createClient } from "graphql-ws";

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

Configure live provider

Add the live provider to your Refine app:
import { Refine } from "@refinedev/core";
import dataProvider, {
  GraphQLClient,
  liveProvider,
} from "@refinedev/graphql";
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>
  );
};
4

Use live updates

Your components will automatically receive real-time updates:
import { useList } from "@refinedev/core";
import gql from "graphql-tag";

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

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

  // Data automatically updates when changes occur
  return <div>{/* Render posts */}</div>;
};

Authentication

Add authentication headers to your GraphQL client:
import { GraphQLClient } from "@refinedev/graphql";

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}` : "",
      },
    });
  },
});

Error Handling

The GraphQL data provider handles GraphQL errors automatically:
import { useCreate } from "@refinedev/core";
import gql from "graphql-tag";

const CREATE_POST = gql`
  mutation CreatePost($input: CreatePostInput!) {
    createPost(input: $input) {
      id
      title
    }
  }
`;

const { mutate } = useCreate();

const handleSubmit = (values) => {
  mutate(
    {
      resource: "posts",
      values,
      meta: {
        gqlMutation: CREATE_POST,
      },
    },
    {
      onError: (error) => {
        // Handle GraphQL errors
        console.error("GraphQL Error:", error.message);
      },
      onSuccess: (data) => {
        console.log("Post created:", data);
      },
    }
  );
};

Complete Example

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

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}` : "",
      },
    });
  },
});

const wsClient = createClient({
  url: "wss://api.example.com/graphql",
  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;

Next Steps

Data Providers Overview

Learn about other data providers

Hasura Provider

Use GraphQL with Hasura

Build docs developers (and LLMs) love