javascript - I need to create admin page using React and MongoDB
问题描述
I have mongoDB installed on amazon server and front-end, written on React.js. I need to create Admin page using 'react-admin' but I don't know how to make it with my mongoDB because they do not provide dataProvider function that 'react-admin' uses to work https://marmelab.com/react-admin/DataProviders.html .
I tried to write my own dataProvider to route and manage my queries and responses, but because of lack of experience I failed.
import { stringify } from 'query-string';
import {
fetchUtils,
GET_LIST,
GET_ONE,
GET_MANY,
GET_MANY_REFERENCE,
CREATE,
UPDATE,
UPDATE_MANY,
DELETE,
DELETE_MANY,
} from 'react-admin';
/**
* Maps react-admin queries to a json-server powered REST API
*
* @see https://github.com/typicode/json-server
* @example
* GET_LIST => GET http://my.api.url/posts?_sort=title&_order=ASC&_start=0&_end=24
* GET_ONE => GET http://my.api.url/posts/123
* GET_MANY => GET http://my.api.url/posts/123, GET http://my.api.url/posts/456, GET http://my.api.url/posts/789
* UPDATE => PUT http://my.api.url/posts/123
* CREATE => POST http://my.api.url/posts/123
* DELETE => DELETE http://my.api.url/posts/123
*/
export default (apiUrl, httpClient = fetchUtils.fetchJson) => {
/**
* @param {String} type One of the constants appearing at the top if this file, e.g. 'UPDATE'
* @param {String} resource Name of the resource to fetch, e.g. 'posts'
* @param {Object} params The data request params, depending on the type
* @returns {Object} { url, options } The HTTP request parameters
*/
const convertDataRequestToHTTP = (type, resource, params) => {
let url = '';
const options = {};
switch (type) {
case GET_LIST: {
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
...fetchUtils.flattenObject(params.filter),
_sort: field,
_order: order,
_start: (page - 1) * perPage,
_end: page * perPage,
};
url = `${apiUrl}/${resource}?${stringify(query)}`;
break;
}
case GET_ONE:
url = `${apiUrl}/${resource}/${params.id}`;
break;
case GET_MANY_REFERENCE: {
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
...fetchUtils.flattenObject(params.filter),
[params.target]: params.id,
_sort: field,
_order: order,
_start: (page - 1) * perPage,
_end: page * perPage,
};
url = `${apiUrl}/${resource}?${stringify(query)}`;
break;
}
case UPDATE:
url = `${apiUrl}/${resource}/${params.id}`;
options.method = 'PUT';
options.body = JSON.stringify(params.data);
break;
case CREATE:
url = `${apiUrl}/${resource}`;
options.method = 'POST';
options.body = JSON.stringify(params.data);
break;
case DELETE:
url = `${apiUrl}/${resource}/${params.id}`;
options.method = 'DELETE';
break;
case GET_MANY: {
const query = {
[`id_like`]: params.ids.join('|'),
};
url = `${apiUrl}/${resource}?${stringify(query)}`;
break;
}
default:
throw new Error(`Unsupported fetch action type ${type}`);
}
console.log(url);
return { url, options };
};
/**
* @param {Object} response HTTP response from fetch()
* @param {String} type One of the constants appearing at the top if this file, e.g. 'UPDATE'
* @param {String} resource Name of the resource to fetch, e.g. 'posts'
* @param {Object} params The data request params, depending on the type
* @returns {Object} Data response
*/
const convertHTTPResponse = (response, type, resource, params) => {
const { headers, json } = response;
switch (type) {
case GET_LIST:
case GET_MANY_REFERENCE:
if (!headers.has('x-total-count')) {
throw new Error(
'The X-Total-Count header is missing in the HTTP Response. The jsonServer 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 X-Total-Count in the Access-Control-Expose-Headers header?'
);
}
return {
data: json,
total: parseInt(
headers
.get('x-total-count')
.split('/')
.pop(),
10
),
};
case CREATE:
return { data: { ...params.data, id: json.id } };
default:
return { data: json };
}
};
/**
* @param {string} type Request type, e.g GET_LIST
* @param {string} resource Resource name, e.g. "posts"
* @param {Object} payload Request parameters. Depends on the request type
* @returns {Promise} the Promise for a data response
*/
return (type, resource, params) => {
console.log(type, resource, params);
// json-server doesn't handle filters on UPDATE route, so we fallback to calling UPDATE n times instead
if (type === UPDATE_MANY) {
return Promise.all(
params.ids.map(id =>
httpClient(`${apiUrl}/${resource}/${id}`, {
method: 'PUT',
body: JSON.stringify(params.data),
})
)
).then(responses => ({
data: responses.map(response => response.json),
}));
}
// json-server doesn't handle filters on DELETE route, so we fallback to calling DELETE n times instead
if (type === DELETE_MANY) {
return Promise.all(
params.ids.map(id =>
httpClient(`${apiUrl}/${resource}/${id}`, {
method: 'DELETE',
})
)
).then(responses => ({
data: responses.map(response => response.json),
}));
}
const { url, options } = convertDataRequestToHTTP(
type,
resource,
params
);
httpClient(url, options).then(response =>
convertHTTPResponse(response, type, resource, params)
);
};
};
This function does :
- GET_LIST => GET http://my.api.url/posts?_sort=title&_order=ASC&_start=0&_end=24
- GET_ONE => GET http://my.api.url/posts/123
- GET_MANY => GET http://my.api.url/posts/123, GET http://my.api.url/posts/456, GET http://my.api.url/posts/789
- UPDATE => PUT http://my.api.url/posts/123
- CREATE => POST http://my.api.url/posts/123
- DELETE => DELETE http://my.api.url/posts/123 */
But I need :
- GET_LIST => GET https://r8p7az51jd.execute-api.us-east-1.amazonaws.com/test/viewpoint?$filter={}&$limit={}&$skip={}&$sort={}
- GET_ONE => GET https://r8p7az51jd.execute-api.us-east-1.amazonaws.com/test/viewpoint?$filter={_id: '1'}
- UPDATE => PUT https://r8p7az51jd.execute-api.us-east-1.amazonaws.com/test/viewpoint?$filter={_id: '1'}
- CREATE => POST https://r8p7az51jd.execute-api.us-east-1.amazonaws.com/test/viewpoint?$filter={_id: '1'}
- DELETE => DELETE https://r8p7az51jd.execute-api.us-east-1.amazonaws.com/test/viewpoint?$filter={_id: '1'} */
解决方案
您必须编写自己的支持您的 API 服务器的 dataProvider.js 文件,只需保持所有函数名称以及返回数据和数据类型相同,React 管理员已经在他们的文档中描述了这一点。请参考:https ://marmelab.com/react-admin/Tutorial.html本页末尾您会看到
推荐阅读
- c# - 如何计算在方法中执行某些操作所需的时间?
- python - 如何在 IIS 上查看调试日志烧瓶 App?
- javascript - 将 csv 文件数据转换为 JavaScript 字典
- node.js - 该命令移动到一个单独的包中:@webpack-cli/serve
- r - 在 r 中使用 par() 函数时如何将列名添加到直方图中
- clickhouse - 点击屋。在集群上创建数据库以超时结束
- reactjs - 使用 api 在 React DOM 中并排控制
- php - 调用时如何在laravel刀片html属性中添加索引?
- node.js - Node.js 不通过管道传输内容
- list - F#:我需要将输出格式化为仅包含逗号分隔的整数,而不是 F# 中的列表格式