-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmock-api.js
126 lines (105 loc) · 3.38 KB
/
mock-api.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// mock-api.js
const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router('mock-db.json');
const middlewares = jsonServer.defaults({ cors: true });
// Set default middlewares (logger, static, cors and no-cache)
server.use(middlewares);
// Add CORS headers
server.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept, Authorization'
);
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
// Handle preflight requests
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
// Add custom routes before JSON Server router
server.get('/echo', (req, res) => {
res.jsonp(req.query);
});
// To handle POST, PUT and PATCH you need to use a body-parser
// You can use the one used by JSON Server
server.use(jsonServer.bodyParser);
// Add custom request handling logic
server.use((req, res, next) => {
// Simulate a 2 second delay in responses (optional - for testing loading states)
// setTimeout(next, 2000);
// Continue to JSON Server router
next();
});
// Custom pagination, search and filtering middleware for posts
router.render = (req, res) => {
let data = res.locals.data;
const route = req.path.replace(/^\//, '');
// Custom handling for posts
if (route === 'posts' && req.method === 'GET') {
const query = req.query;
const pageIndex = parseInt(query.pageIndex) || 0;
const pageSize = parseInt(query.pageSize) || 10;
const search = query.search || '';
const status =
query.status !== undefined ? parseInt(query.status) : undefined;
// Filter by search term
if (search) {
data = data.filter(
(item) =>
item.title?.toLowerCase().includes(search.toLowerCase()) ||
item.excerpt?.toLowerCase().includes(search.toLowerCase())
);
}
// Filter by status
if (status !== undefined) {
data = data.filter((item) => item.status === status);
}
// Get total before pagination
const totalItems = data.length;
// Apply pagination
const startIndex = pageIndex * pageSize;
const paginatedItems = data.slice(startIndex, startIndex + pageSize);
// Make sure the id field is a number, not a string (json-server issue)
const formattedItems = paginatedItems.map((item) => ({
...item,
id: Number(item.id)
}));
// Return formatted response with pagination info
return res.jsonp({
items: formattedItems,
totalItems,
totalPages: Math.ceil(totalItems / pageSize),
pageIndex,
pageSize
});
}
// For single post, ensure ID is a number
if (route.startsWith('posts/') && req.method === 'GET') {
if (data && typeof data === 'object') {
return res.jsonp({
...data,
id: Number(data.id)
});
}
}
// Default response for other routes
res.jsonp(data);
};
// Use custom rewriter for API paths
server.use(
jsonServer.rewriter({
'/api/v2/rest/mix-portal/mix-post': '/posts',
'/api/v2/rest/mix-portal/mix-post/:id': '/posts/:id',
'/api/v2/rest/mix-portal/mix-post/remove-cache/:id': '/posts/:id'
})
);
// Use the router
server.use(router);
// Start server
const port = 3001;
server.listen(port, () => {
console.log(`Mock API Server is running on http://localhost:${port}`);
});