Skip to main content

Introduction

The Simple REST data provider is designed for REST APIs that follow the json-server conventions. It provides a straightforward way to connect Refine applications to REST APIs with standard CRUD operations.

Installation

Install the Simple REST data provider package:
npm install @refinedev/simple-rest

Basic Usage

Import and configure the data provider with your API URL:
import { Refine } from "@refinedev/core";
import dataProvider from "@refinedev/simple-rest";

const App = () => {
  return (
    <Refine
      dataProvider={dataProvider("https://api.example.com")}
      // ... other props
    >
      {/* Your app content */}
    </Refine>
  );
};

API Expectations

The Simple REST data provider expects your API to follow these conventions:

Get List

GET https://api.example.com/posts?_start=0&_end=10&_sort=id&_order=desc
Response:
[
  { "id": 1, "title": "Post 1" },
  { "id": 2, "title": "Post 2" }
]
The API should return the total count in the x-total-count header:
x-total-count: 42

Get One

GET https://api.example.com/posts/1
Response:
{ "id": 1, "title": "Post 1", "content": "Content" }

Get Many

GET https://api.example.com/posts?id=1&id=2&id=3
Response:
[
  { "id": 1, "title": "Post 1" },
  { "id": 2, "title": "Post 2" },
  { "id": 3, "title": "Post 3" }
]

Create

POST https://api.example.com/posts
Content-Type: application/json

{ "title": "New Post", "content": "Content" }
Response:
{ "id": 4, "title": "New Post", "content": "Content" }

Update

PATCH https://api.example.com/posts/1
Content-Type: application/json

{ "title": "Updated Post" }
Response:
{ "id": 1, "title": "Updated Post", "content": "Content" }

Delete

DELETE https://api.example.com/posts/1
Response:
{ "id": 1 }

Configuration

1

Basic setup

Configure the data provider with your API URL:
import { Refine } from "@refinedev/core";
import dataProvider from "@refinedev/simple-rest";

const App = () => (
  <Refine
    dataProvider={dataProvider("https://api.example.com")}
  >
    {/* ... */}
  </Refine>
);
2

Custom HTTP client

You can pass a custom Axios instance for advanced configuration:
import dataProvider from "@refinedev/simple-rest";
import axios from "axios";

const httpClient = axios.create({
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
  },
});

const App = () => (
  <Refine
    dataProvider={dataProvider("https://api.example.com", httpClient)}
  >
    {/* ... */}
  </Refine>
);
3

Using with resources

Define your resources to work with the data provider:
<Refine
  dataProvider={dataProvider("https://api.example.com")}
  resources={[
    {
      name: "posts",
      list: "/posts",
      create: "/posts/create",
      edit: "/posts/edit/:id",
      show: "/posts/show/:id",
    },
    {
      name: "categories",
      list: "/categories",
    },
  ]}
>
  {/* ... */}
</Refine>

Advanced Usage

Custom Headers per Request

You can pass custom headers using the meta property:
import { useList } from "@refinedev/core";

const { data } = useList({
  resource: "posts",
  meta: {
    headers: {
      "x-custom-header": "custom-value",
    },
  },
});

Custom HTTP Method

Override the default HTTP method:
import { useList } from "@refinedev/core";

const { data } = useList({
  resource: "posts",
  meta: {
    method: "post", // Use POST instead of GET
  },
});

Filtering

The Simple REST data provider supports various filter operators:
import { useList } from "@refinedev/core";

const { data } = useList({
  resource: "posts",
  filters: [
    {
      field: "title",
      operator: "contains",
      value: "hello",
    },
    {
      field: "status",
      operator: "eq",
      value: "published",
    },
  ],
});
This generates a request like:
GET /posts?title_like=hello&status=published

Sorting

Sort your data using the sorters property:
import { useList } from "@refinedev/core";

const { data } = useList({
  resource: "posts",
  sorters: [
    {
      field: "createdAt",
      order: "desc",
    },
  ],
});
This generates a request like:
GET /posts?_sort=createdAt&_order=desc

Pagination

Pagination is handled automatically:
import { useList } from "@refinedev/core";

const { data } = useList({
  resource: "posts",
  pagination: {
    current: 2,
    pageSize: 20,
  },
});
This generates a request like:
GET /posts?_start=20&_end=40

Complete Example

Here’s a complete example of using the Simple REST data provider:
import { Refine } from "@refinedev/core";
import dataProvider from "@refinedev/simple-rest";
import routerProvider from "@refinedev/react-router";
import { BrowserRouter } from "react-router";
import axios from "axios";

const httpClient = axios.create({
  headers: {
    "Authorization": `Bearer ${localStorage.getItem("token")}`,
  },
});

// Add request interceptor for auth
httpClient.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem("token");
    if (token) {
      config.headers["Authorization"] = `Bearer ${token}`;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

const App = () => {
  return (
    <BrowserRouter>
      <Refine
        dataProvider={dataProvider(
          "https://api.example.com",
          httpClient
        )}
        routerProvider={routerProvider}
        resources={[
          {
            name: "posts",
            list: "/posts",
            create: "/posts/create",
            edit: "/posts/edit/:id",
            show: "/posts/show/:id",
          },
          {
            name: "categories",
            list: "/categories",
          },
        ]}
      >
        {/* Your routes and pages */}
      </Refine>
    </BrowserRouter>
  );
};

export default App;

Error Handling

The Simple REST data provider automatically handles HTTP errors. You can catch and handle them in your components:
import { useCreate } from "@refinedev/core";

const { mutate } = useCreate();

const handleSubmit = (values) => {
  mutate(
    {
      resource: "posts",
      values,
    },
    {
      onError: (error) => {
        console.error("Failed to create post:", error);
      },
      onSuccess: (data) => {
        console.log("Post created:", data);
      },
    }
  );
};

Supported Operators

The Simple REST data provider supports the following filter operators:
  • eq: Equals (e.g., status=published)
  • ne: Not equals (e.g., status_ne=draft)
  • lt: Less than (e.g., views_lt=100)
  • lte: Less than or equal (e.g., views_lte=100)
  • gt: Greater than (e.g., views_gt=100)
  • gte: Greater than or equal (e.g., views_gte=100)
  • contains: Contains (e.g., title_like=hello)
  • in: In array (e.g., id=1&id=2&id=3)
  • nin: Not in array

Next Steps

Data Providers Overview

Learn about other data providers

Creating Custom Provider

Build your own data provider

Build docs developers (and LLMs) love