json-api-mocker 1.1.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
package/CONFIG.ch.md ADDED
@@ -0,0 +1,305 @@
1
+ # JSON API Mocker 配置指南
2
+
3
+ 本文档将帮助你理解和编写 `data.json` 配置文件。
4
+
5
+ ## 配置文件结构
6
+
7
+ ```json
8
+ {
9
+ "server": {
10
+ "port": 8080,
11
+ "baseProxy": "/api"
12
+ },
13
+ "routes": []
14
+ }
15
+ ```
16
+
17
+ ## 配置项详解
18
+
19
+ ### 1. 服务器配置 (server)
20
+
21
+ | 字段 | 类型 | 必填 | 默认值 | 说明 |
22
+ |------|------|------|--------|------|
23
+ | port | number | 否 | 8080 | 服务器端口号 |
24
+ | baseProxy | string | 否 | "/api" | API 的基础路径 |
25
+
26
+ ### 2. 路由配置 (routes)
27
+
28
+ routes 是一个数组,每个元素都是一个路由配置对象:
29
+
30
+ ```json
31
+ {
32
+ "path": "/users",
33
+ "methods": {
34
+ "get": {},
35
+ "post": {},
36
+ "put": {},
37
+ "delete": {}
38
+ }
39
+ }
40
+ ```
41
+
42
+ #### 2.1 路由基础配置
43
+
44
+ | 字段 | 类型 | 必填 | 说明 |
45
+ |------|------|------|------|
46
+ | path | string | 是 | 路由路径,支持参数如 `/users/:id` |
47
+ | methods | object | 是 | HTTP 方法配置对象 |
48
+
49
+ #### 2.2 方法配置 (methods)
50
+
51
+ 每个 HTTP 方法可以包含以下配置:
52
+
53
+ | 字段 | 类型 | 必填 | 说明 |
54
+ |------|------|------|------|
55
+ | type | string | 否 | 响应类型:"array" 或 "object" |
56
+ | response | any | 否 | 静态响应数据 |
57
+ | mock | object | 否 | Mock.js 配置 |
58
+ | pagination | object | 否 | 分页配置 |
59
+ | requestSchema | object | 否 | 请求体验证模式 |
60
+
61
+ ### 3. Mock 数据配置 (mock)
62
+
63
+ ```json
64
+ {
65
+ "mock": {
66
+ "enabled": true,
67
+ "total": 100,
68
+ "template": {
69
+ "id|+1": 1,
70
+ "name": "@cname",
71
+ "email": "@email"
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ | 字段 | 类型 | 必填 | 说明 |
78
+ |------|------|------|------|
79
+ | enabled | boolean | 是 | 是否启用 mock 数据 |
80
+ | total | number | 是 | 生成数据的总条数 |
81
+ | template | object | 是 | Mock.js 的数据模板 |
82
+
83
+ ### 4. 分页配置 (pagination)
84
+
85
+ ```json
86
+ {
87
+ "pagination": {
88
+ "enabled": true,
89
+ "pageSize": 10
90
+ }
91
+ }
92
+ ```
93
+
94
+ | 字段 | 类型 | 必填 | 默认值 | 说明 |
95
+ |------|------|------|--------|------|
96
+ | enabled | boolean | 否 | false | 是否启用分页 |
97
+ | pageSize | number | 否 | 10 | 每页数据条数 |
98
+
99
+ ### 5. 请求验证配置 (requestSchema)
100
+
101
+ ```json
102
+ {
103
+ "requestSchema": {
104
+ "name": "string",
105
+ "age": "number",
106
+ "email": "string"
107
+ }
108
+ }
109
+ ```
110
+
111
+ ## Mock.js 模板使用说明
112
+
113
+ ### 常用模板示例
114
+
115
+ - `@cname` - 生成中文姓名
116
+ - `@name` - 生成英文姓名
117
+ - `@email` - 生成邮箱地址
118
+ - `@datetime` - 生成日期时间
119
+ - `@image` - 生成图片链接
120
+ - `@city` - 生成城市名
121
+ - `@id` - 生成随机 ID
122
+ - `@guid` - 生成 GUID
123
+ - `@ctitle` - 生成中文标题
124
+ - `@cparagraph` - 生成中文段落
125
+ - `|+1` - 自增数字
126
+
127
+ ## 完整配置示例
128
+
129
+ ### 1. 用户管理接口
130
+
131
+ ```json
132
+ {
133
+ "server": {
134
+ "port": 8080,
135
+ "baseProxy": "/api"
136
+ },
137
+ "routes": [
138
+ {
139
+ "path": "/users",
140
+ "methods": {
141
+ "get": {
142
+ "type": "array",
143
+ "mock": {
144
+ "enabled": true,
145
+ "total": 100,
146
+ "template": {
147
+ "id|+1": 1,
148
+ "name": "@cname",
149
+ "age|18-60": 1,
150
+ "email": "@email",
151
+ "address": "@city(true)"
152
+ }
153
+ },
154
+ "pagination": {
155
+ "enabled": true,
156
+ "pageSize": 10
157
+ }
158
+ },
159
+ "post": {
160
+ "requestSchema": {
161
+ "name": "string",
162
+ "age": "number",
163
+ "email": "string"
164
+ },
165
+ "response": {
166
+ "success": true,
167
+ "message": "创建成功"
168
+ }
169
+ }
170
+ }
171
+ }
172
+ ]
173
+ }
174
+ ```
175
+
176
+ ### 2. 文章管理接口(带嵌套数据)
177
+
178
+ ```json
179
+ {
180
+ "path": "/articles",
181
+ "methods": {
182
+ "get": {
183
+ "type": "array",
184
+ "mock": {
185
+ "enabled": true,
186
+ "total": 50,
187
+ "template": {
188
+ "id|+1": 1,
189
+ "title": "@ctitle",
190
+ "content": "@cparagraph",
191
+ "author": {
192
+ "id|+1": 100,
193
+ "name": "@cname",
194
+ "avatar": "@image('100x100')"
195
+ },
196
+ "comments|0-10": [{
197
+ "id|+1": 1,
198
+ "content": "@csentence",
199
+ "user": "@cname",
200
+ "createTime": "@datetime"
201
+ }]
202
+ }
203
+ }
204
+ }
205
+ }
206
+ }
207
+ ```
208
+
209
+ ## 使用技巧
210
+
211
+ ### 1. 动态路由参数
212
+ ```json
213
+ {
214
+ "path": "/users/:id/posts",
215
+ "methods": {
216
+ "get": {
217
+ "type": "array",
218
+ "mock": {
219
+ "enabled": true,
220
+ "total": 10,
221
+ "template": {
222
+ "id|+1": 1,
223
+ "title": "@ctitle",
224
+ "content": "@cparagraph"
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ ```
231
+
232
+ ### 2. 分页查询
233
+ ```bash
234
+ # 获取第二页,每页10条数据
235
+ curl http://localhost:8080/api/users?page=2&pageSize=10
236
+ ```
237
+
238
+ ### 3. 数据范围生成
239
+ ```json
240
+ {
241
+ "template": {
242
+ "age|18-60": 1, // 生成18-60之间的数字
243
+ "score|1-100.1": 1, // 生成1-100之间的浮点数,保留1位小数
244
+ "items|1-5": ["item"] // 生成1-5个重复项
245
+ }
246
+ }
247
+ ```
248
+
249
+ ## 注意事项
250
+
251
+ 1. **路径参数**
252
+ - 动态路由参数使用 `:参数名` 格式
253
+ - 例如:`/users/:id/posts/:postId`
254
+
255
+ 2. **Mock 数据**
256
+ - `enabled` 为 `true` 时才会生成 mock 数据
257
+ - `template` 中可以使用所有 Mock.js 支持的语法
258
+
259
+ 3. **分页**
260
+ - 启用分页后,可通过 `?page=1&pageSize=10` 访问分页数据
261
+ - 响应头会包含 `X-Total-Count` 表示总数据量
262
+
263
+ 4. **数据持久化**
264
+ - POST、PUT、DELETE 操作会自动保存到 data.json 文件
265
+ - 重启服务器后数据仍然保留
266
+
267
+ ## 最佳实践
268
+
269
+ 1. **合理使用 Mock 数据**
270
+ ```json
271
+ {
272
+ "mock": {
273
+ "enabled": true,
274
+ "total": 100,
275
+ "template": {
276
+ // 使用自增ID避免重复
277
+ "id|+1": 1,
278
+ // 使用合适的数据类型
279
+ "age|18-60": 1
280
+ }
281
+ }
282
+ }
283
+ ```
284
+
285
+ 2. **适当的分页配置**
286
+ ```json
287
+ {
288
+ "pagination": {
289
+ "enabled": true,
290
+ "pageSize": 10 // 根据数据量设置合适的页大小
291
+ }
292
+ }
293
+ ```
294
+
295
+ 3. **请求验证**
296
+ ```json
297
+ {
298
+ "requestSchema": {
299
+ // 确保必要的字段都有类型验证
300
+ "name": "string",
301
+ "age": "number",
302
+ "email": "string"
303
+ }
304
+ }
305
+ ```
package/CONFIG.md ADDED
@@ -0,0 +1,271 @@
1
+ # JSON API Mocker Configuration Guide
2
+
3
+ A comprehensive guide to help you understand and write the `data.json` configuration file.
4
+
5
+ ## Configuration Structure
6
+
7
+ ```json
8
+ {
9
+ "server": {
10
+ "port": 8080,
11
+ "baseProxy": "/api"
12
+ },
13
+ "routes": []
14
+ }
15
+ ```
16
+
17
+ ## Configuration Details
18
+
19
+ ### 1. Server Configuration (server)
20
+
21
+ | Field | Type | Required | Default | Description |
22
+ |-------|------|----------|---------|-------------|
23
+ | port | number | No | 8080 | Server port number |
24
+ | baseProxy | string | No | "/api" | Base path for all APIs |
25
+
26
+ ### 2. Routes Configuration (routes)
27
+
28
+ Routes is an array where each element is a route configuration object:
29
+
30
+ ```json
31
+ {
32
+ "path": "/users",
33
+ "methods": {
34
+ "get": {},
35
+ "post": {},
36
+ "put": {},
37
+ "delete": {}
38
+ }
39
+ }
40
+ ```
41
+
42
+ #### 2.1 Route Basic Configuration
43
+
44
+ | Field | Type | Required | Description |
45
+ |-------|------|----------|-------------|
46
+ | path | string | Yes | Route path, supports parameters like `/users/:id` |
47
+ | methods | object | Yes | HTTP methods configuration object |
48
+
49
+ #### 2.2 Method Configuration (methods)
50
+
51
+ Each HTTP method can include the following configurations:
52
+
53
+ | Field | Type | Required | Description |
54
+ |-------|------|----------|-------------|
55
+ | type | string | No | Response type: "array" or "object" |
56
+ | response | any | No | Static response data |
57
+ | mock | object | No | Mock.js configuration |
58
+ | pagination | object | No | Pagination configuration |
59
+ | requestSchema | object | No | Request body validation schema |
60
+
61
+ ### 3. Mock Data Configuration (mock)
62
+
63
+ ```json
64
+ {
65
+ "mock": {
66
+ "enabled": true,
67
+ "total": 100,
68
+ "template": {
69
+ "id|+1": 1,
70
+ "name": "@name",
71
+ "email": "@email"
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ | Field | Type | Required | Description |
78
+ |-------|------|----------|-------------|
79
+ | enabled | boolean | Yes | Enable/disable mock data |
80
+ | total | number | Yes | Total number of records to generate |
81
+ | template | object | Yes | Mock.js data template |
82
+
83
+ ### 4. Pagination Configuration (pagination)
84
+
85
+ ```json
86
+ {
87
+ "pagination": {
88
+ "enabled": true,
89
+ "pageSize": 10
90
+ }
91
+ }
92
+ ```
93
+
94
+ | Field | Type | Required | Default | Description |
95
+ |-------|------|----------|---------|-------------|
96
+ | enabled | boolean | No | false | Enable/disable pagination |
97
+ | pageSize | number | No | 10 | Number of items per page |
98
+
99
+ ### 5. Request Validation Configuration (requestSchema)
100
+
101
+ ```json
102
+ {
103
+ "requestSchema": {
104
+ "name": "string",
105
+ "age": "number",
106
+ "email": "string"
107
+ }
108
+ }
109
+ ```
110
+
111
+ ## Complete Configuration Examples
112
+
113
+ ### 1. Basic User CRUD API
114
+
115
+ ```json
116
+ {
117
+ "server": {
118
+ "port": 8080,
119
+ "baseProxy": "/api"
120
+ },
121
+ "routes": [
122
+ {
123
+ "path": "/users",
124
+ "methods": {
125
+ "get": {
126
+ "type": "array",
127
+ "mock": {
128
+ "enabled": true,
129
+ "total": 100,
130
+ "template": {
131
+ "id|+1": 1,
132
+ "name": "@name",
133
+ "age|18-60": 1,
134
+ "email": "@email",
135
+ "address": "@city"
136
+ }
137
+ },
138
+ "pagination": {
139
+ "enabled": true,
140
+ "pageSize": 10
141
+ }
142
+ },
143
+ "post": {
144
+ "requestSchema": {
145
+ "name": "string",
146
+ "age": "number",
147
+ "email": "string"
148
+ },
149
+ "response": {
150
+ "success": true,
151
+ "message": "Created successfully"
152
+ }
153
+ }
154
+ }
155
+ }
156
+ ]
157
+ }
158
+ ```
159
+
160
+ ### 2. Articles API with Nested Data
161
+
162
+ ```json
163
+ {
164
+ "path": "/articles",
165
+ "methods": {
166
+ "get": {
167
+ "type": "array",
168
+ "mock": {
169
+ "enabled": true,
170
+ "total": 50,
171
+ "template": {
172
+ "id|+1": 1,
173
+ "title": "@title",
174
+ "content": "@paragraph",
175
+ "author": {
176
+ "id|+1": 100,
177
+ "name": "@name",
178
+ "avatar": "@image('100x100')"
179
+ },
180
+ "comments|0-10": [{
181
+ "id|+1": 1,
182
+ "content": "@sentence",
183
+ "user": "@name",
184
+ "createTime": "@datetime"
185
+ }]
186
+ }
187
+ }
188
+ }
189
+ }
190
+ }
191
+ ```
192
+
193
+ ### 3. Dynamic Route Parameters Example
194
+
195
+ ```json
196
+ {
197
+ "path": "/users/:id/posts",
198
+ "methods": {
199
+ "get": {
200
+ "type": "array",
201
+ "mock": {
202
+ "enabled": true,
203
+ "total": 10,
204
+ "template": {
205
+ "id|+1": 1,
206
+ "title": "@title",
207
+ "content": "@paragraph"
208
+ }
209
+ }
210
+ }
211
+ }
212
+ }
213
+ ```
214
+
215
+ ## Important Notes
216
+
217
+ 1. **Route Parameters**
218
+ - Dynamic route parameters use `:paramName` format
219
+ - Example: `/users/:id/posts/:postId`
220
+
221
+ 2. **Mock Data**
222
+ - Mock data generation only works when `enabled` is `true`
223
+ - `template` supports all Mock.js syntax
224
+
225
+ 3. **Pagination**
226
+ - When enabled, use `?page=1&pageSize=10` to access paginated data
227
+ - Response headers include `X-Total-Count` for total count
228
+
229
+ 4. **Data Persistence**
230
+ - POST, PUT, DELETE operations automatically save to data.json
231
+ - Data persists after server restart
232
+
233
+ ## Best Practices
234
+
235
+ 1. **Effective Use of Mock Data**
236
+ ```json
237
+ {
238
+ "mock": {
239
+ "enabled": true,
240
+ "total": 100,
241
+ "template": {
242
+ // Use auto-increment for IDs
243
+ "id|+1": 1,
244
+ // Use appropriate data types
245
+ "age|18-60": 1
246
+ }
247
+ }
248
+ }
249
+ ```
250
+
251
+ 2. **Proper Pagination Settings**
252
+ ```json
253
+ {
254
+ "pagination": {
255
+ "enabled": true,
256
+ "pageSize": 10 // Set appropriate page size based on data volume
257
+ }
258
+ }
259
+ ```
260
+
261
+ 3. **Request Validation**
262
+ ```json
263
+ {
264
+ "requestSchema": {
265
+ // Ensure all required fields have type validation
266
+ "name": "string",
267
+ "age": "number",
268
+ "email": "string"
269
+ }
270
+ }
271
+ ```
package/dist/server.d.ts CHANGED
@@ -5,6 +5,7 @@ export declare class MockServer {
5
5
  private configPath;
6
6
  constructor(config: Config, configPath?: string);
7
7
  private setupMiddleware;
8
+ private logRequest;
8
9
  private generateMockData;
9
10
  private handleRequest;
10
11
  private setupRoutes;
package/dist/server.js CHANGED
@@ -10,6 +10,23 @@ const cors_1 = __importDefault(require("cors"));
10
10
  class MockServer {
11
11
  constructor(config, configPath = 'data.json') {
12
12
  this.app = (0, express_1.default)();
13
+ this.logRequest = (req, res, next) => {
14
+ const startTime = Date.now();
15
+ const requestId = Math.random().toString(36).substring(7);
16
+ console.log(`[${new Date().toISOString()}] Request ${requestId}:`);
17
+ console.log(` Method: ${req.method}`);
18
+ console.log(` URL: ${req.url}`);
19
+ console.log(` Query Params: ${JSON.stringify(req.query)}`);
20
+ console.log(` Body: ${JSON.stringify(req.body)}`);
21
+ res.on('finish', () => {
22
+ const duration = Date.now() - startTime;
23
+ console.log(`[${new Date().toISOString()}] Response ${requestId}:`);
24
+ console.log(` Status: ${res.statusCode}`);
25
+ console.log(` Duration: ${duration}ms`);
26
+ console.log('----------------------------------------');
27
+ });
28
+ next();
29
+ };
13
30
  this.config = config;
14
31
  this.configPath = configPath;
15
32
  this.setupMiddleware();
@@ -18,6 +35,7 @@ class MockServer {
18
35
  setupMiddleware() {
19
36
  this.app.use((0, cors_1.default)());
20
37
  this.app.use(express_1.default.json());
38
+ this.app.use(this.logRequest);
21
39
  }
22
40
  generateMockData(config) {
23
41
  try {
@@ -27,17 +45,16 @@ class MockServer {
27
45
  [`data|${total}`]: [template]
28
46
  }).data;
29
47
  }
30
- return config.response || [];
48
+ return config.response;
31
49
  }
32
50
  catch (error) {
33
- console.error('生成 Mock 数据时出错:', error);
34
- return config.response || [];
51
+ console.error('Error generating mock data:', error);
52
+ return config.response;
35
53
  }
36
54
  }
37
55
  handleRequest(config) {
38
56
  return (req, res) => {
39
57
  try {
40
- console.log(`收到请求: ${req.method} ${req.url}`);
41
58
  let responseData = this.generateMockData(config);
42
59
  if (config.pagination?.enabled && Array.isArray(responseData)) {
43
60
  const page = parseInt(req.query.page) || 1;
@@ -51,8 +68,8 @@ class MockServer {
51
68
  res.json(responseData);
52
69
  }
53
70
  catch (error) {
54
- console.error('处理请求时出错:', error);
55
- res.status(500).json({ error: '服务器内部错误' });
71
+ console.error('Error handling request:', error);
72
+ res.status(500).json({ error: 'Internal server error' });
56
73
  }
57
74
  };
58
75
  }
package/dist/types.d.ts CHANGED
@@ -14,11 +14,10 @@ export interface MockConfig {
14
14
  }
15
15
  export interface MethodConfig {
16
16
  type?: 'array' | 'object';
17
- pagination?: PaginationConfig;
18
- mock?: MockConfig;
19
17
  response?: any;
18
+ mock?: MockConfig;
19
+ pagination?: PaginationConfig;
20
20
  requestSchema?: Record<string, string>;
21
- params?: string[];
22
21
  }
23
22
  export interface RouteConfig {
24
23
  path: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-api-mocker",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "一个基于 JSON 配置的 Mock 服务器",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -10,7 +10,9 @@
10
10
  "files": [
11
11
  "dist",
12
12
  "README.md",
13
- "README.ch.md"
13
+ "README.ch.md",
14
+ "CONFIG.md",
15
+ "CONFIG.ch.md"
14
16
  ],
15
17
  "scripts": {
16
18
  "dev": "nodemon",