Skip to content

Instantly share code, notes, and snippets.

@deluan
Created June 11, 2021 17:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deluan/80a415b7ff5b7cc32c32b8322923541d to your computer and use it in GitHub Desktop.
Save deluan/80a415b7ff5b7cc32c32b8322923541d to your computer and use it in GitHub Desktop.
import { stringify } from "query-string";
import { fetchUtils } from "ra-core";
const bootDataProvider = (
apiUrl,
httpClient = fetchUtils.fetchJson,
countHeader = "X-Total-Count"
) => ({
getList: (resource, params) => {
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const rangeStart = page - 1;
const rangeEnd = perPage;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([rangeStart, rangeEnd]),
filter: JSON.stringify(params.filter),
};
const url = `${apiUrl}/${resource}?${stringify(query)}`;
return httpClient(url).then(({ headers, json }) => {
if (!headers.has(countHeader)) {
throw new Error(
`The ${countHeader} header is missing in the HTTP Response. The simple REST data provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare ${countHeader} in the Access-Control-Expose-Headers header?`
);
}
return {
data: json.content,
total: json.total,
};
});
},
getOne: (resource, params) =>
httpClient(`${apiUrl}/${resource}/${params.id}`).then(({ json }) => ({
data: json,
})),
getMany: (resource, params) => {
const query = {
filter: JSON.stringify({ id: params.ids }),
};
const url = `${apiUrl}/${resource}?${stringify(query)}`;
return httpClient(url).then(({ json }) => ({ data: json.content }));
},
getManyReference: (resource, params) => {
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
filter: JSON.stringify({
...params.filter,
[params.target]: params.id,
}),
};
const url = `${apiUrl}/${resource}?${stringify(query)}`;
return httpClient(url).then(({ headers, json }) => {
if (!headers.has(countHeader)) {
throw new Error(
`The ${countHeader} header is missing in the HTTP Response. The simple REST data provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare ${countHeader} in the Access-Control-Expose-Headers header?`
);
}
return {
data: json.content,
total: json.total,
};
});
},
update: (resource, params) =>
httpClient(`${apiUrl}/${resource}/${params.id}`, {
method: "PUT",
body: JSON.stringify(params.data),
}).then(({ json }) => ({ data: json })),
// simple-rest doesn't handle provide an updateMany route, so we fallback to calling update n times instead
updateMany: (resource, params) =>
Promise.all(
params.ids.map((id) =>
httpClient(`${apiUrl}/${resource}/${id}`, {
method: "PUT",
body: JSON.stringify(params.data),
})
)
).then((responses) => ({ data: responses.map(({ json }) => json.id) })),
create: (resource, params) =>
httpClient(`${apiUrl}/${resource}`, {
method: "POST",
body: JSON.stringify(params.data),
}).then(({ json }) => ({
data: { ...params.data, id: json.id },
})),
delete: (resource, params) =>
httpClient(`${apiUrl}/${resource}/${params.id}`, {
method: "DELETE",
headers: new Headers({
"Content-Type": "text/plain",
}),
}).then(({ json }) => ({ data: json })),
// simple-rest doesn't handle filters on DELETE route, so we fallback to calling DELETE n times instead
deleteMany: (resource, params) =>
Promise.all(
params.ids.map((id) =>
httpClient(`${apiUrl}/${resource}/${id}`, {
method: "DELETE",
headers: new Headers({
"Content-Type": "text/plain",
}),
})
)
).then((responses) => ({
data: responses.map(({ json }) => json.id),
})),
});
export default bootDataProvider;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment