json-server + mock.js to build mock service
Introduction
Front-end developers should be familiar with the pain of building pages when the backend has defined APIs but cannot provide data services. Therefore, it is most necessary to set up a local service that can mock data.
Tools Used: json-server for providing services, mockjs for simulating data.
Directory Structure of This Article:
mock
├── mockDB
│ └── test.js
├── db.js
└── server.js
一、Practice
1、Install Dependencies
npm install json-server mockjs --D
2、Write db.json Route Mapping Table This is a file consisting of API paths and the corresponding return contents, for example:
{
"user_info": {
"id": 1000,
"course_name": "马连白米且",
"autor": "袁明",
"college": "金并即总变史",
"category_Id": 2
}
}
"user_info" here is your API endpoint path, and the value following it is the content returned by this endpoint.
If you have started a json-server service locally at http://localhost:6666, then accessing http://localhost:6666/user_info will give you the following content:
{
"id": 1000,
"course_name": "马连白米且",
"autor": "袁明",
"college": "金并即总变史",
"category_Id": 2
}
But here's the problem: by simply defining a db.json file like this, every time you access http://localhost:6666/user_info, you will get the same data, and it won't change. This is not the effect we want. We want to get different data each time we access it.
3、Write mock data that changes every time
mock/mockDB/test.js
// import mock.js
let Mock = require('mockjs');
let Random = Mock.Random;
// Write a function that dynamically generates mock data using mock.js
// I've seen many tutorials that directly output an object here, so each visit gets the same data. This does not meet expectations.
// Here we use a function wrapper so that each time the API is accessed, the function is executed once, resulting in new mock data.
function testList() {
const monitorList = [];
for (var i = 0; i < 3; i++) {
monitorList.push(
Mock.mock({
userid: '25788869998_1562054852076593528',
appid: Random.natural(100, 3000),
content: Random.cparagraph(2, 4),
timestamp: 1562054852,
})
);
}
// Return the data format you want here
return {
success: true,
data: monitorList,
message: 'Success',
};
}
// Expose the testList function with the API path as the key.
exports.user_info = testList;
4、Write the code to assemble the db.json file
As mentioned earlier, json-server requires a JSON file as a route configuration table, with the following format:
{
"user_info": {
"id": 1000,
"course_name": "马连白米且",
"autor": "袁明",
"college": "金并即总变史",
"category_Id": 2
}
}
It is very important to note: In the route configuration, the API path is the key, and the returned data is the value. This value must be an array or object; it cannot be a function. The following format would result in an error:
{
"user_info": function () {
return {
"id": 1000,
"course_name": "马连白米且",
}
}
}
To ensure that each request to the same endpoint returns different data, the value in the route configuration must be a function. This is why we define a function in mock/mockDB/test.js. The principle of json-server is to get the access path, then find the corresponding value in the route configuration table, and finally return it to the user. If it is written as a fixed object or array, then each visit will get the same data.
mock/db.js
To read all mock data files in the mockDB folder, assemble them into the format of the route configuration table mentioned above, and then expose them, you can use require.context provided by webpack to read all files, or use Node.js's fs module to read all files. I won't go into detail here, but I'll briefly explain the process.
// If there are the following files in the mockDB folder:
let test1 = require('./mockDB/test.js');
let test2 = require('./mockDB/test2.js');
// Define a collection object here
let dbJson = {
func: {},
json: {},
}
// Collect mock functions, which will be used in server.js
dbJson.func = {
...test1,
...test2,
};
// Get all api paths
let apiPath = Object.keys(dbJson.func);
/ Assemble the route table required by json-server. Why are all the values empty objects here?
// As mentioned earlier, the values in the route table must be objects or arrays. But all the definitions in our mockDB folder are mock functions, so to ensure that the route table is correct, we need to reassemble a route table that conforms to the format.
apiPath.forEach(item => {
dbJson.json[item] = {};
});
exports.dbJson = dbJson.json;
exports.dbFunc = dbJson.func;
5、Create json-server local service
const jsonServer = require('json-server');
// Create json-server instance
const server = jsonServer.create();
const jsonDB = require('./db');
// Pass the route configuration table to generate the routes table
const router = jsonServer.router(jsonDB.dbJson);
const middlewares = jsonServer.defaults();
// This part is quite important.
// The purpose is to redefine the data returned by the routes. That is to say, every time a route is visited and a response is returned, the response data can be redefined through router.render.
// Because we collected the mock functions in db.js into the dbJson.func object.
router.render = (req, res) => {
// Extract the path based on the requested URL.
// For example, in general, res.url is in the format of /user_info?id=1234.
let end = req.url.indexOf('?');
let apiName = req.url.slice(1, end) || '';
// Retrieve the corresponding mock function based on the apiName, and then return the mock data generated by the mock function.
// Because this function is executed every time a response is returned, new mock data is obtained each time.
let response = dbJson.func[apiName] && dbJson.func[apiName]();
res.send(response || {}));
};
server.use(middlewares);
server.use(router);
server.listen(6666, () => {
console.log('JSON Server is running');
});
6、Start Server
node mock/server.js
7、Conclusion
This article is a personal practical approach. If there are any mistakes or inaccuracies, I apologize and welcome corrections. Thank you.