response-kit 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +557 -146
- package/docs/error-response.md +582 -101
- package/docs/getting-started.md +436 -38
- package/docs/pagination.md +542 -77
- package/docs/success-response.md +326 -61
- package/index.d.ts +122 -20
- package/package.json +67 -51
- package/src/core/config.js +94 -0
- package/src/helpers/error.js +104 -0
- package/src/helpers/pagination.js +41 -0
- package/src/helpers/success.js +52 -0
- package/src/helpers/validation.js +32 -0
- package/src/index.js +83 -6
- package/src/middleware/asyncHandler.js +14 -0
- package/src/middleware/response.js +69 -0
- package/src/types/index.js +71 -0
- package/src/utils/constants.js +39 -0
package/docs/getting-started.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
# Getting Started
|
|
1
|
+
# Getting Started with Response Kit v2
|
|
2
2
|
|
|
3
|
-
This guide will help you
|
|
3
|
+
This guide will help you get started with Response Kit v2, covering installation, basic setup, and common usage patterns.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
10
|
npm install response-kit
|
|
@@ -10,74 +12,470 @@ npm install response-kit
|
|
|
10
12
|
|
|
11
13
|
---
|
|
12
14
|
|
|
13
|
-
##
|
|
15
|
+
## Basic Setup
|
|
16
|
+
|
|
17
|
+
### Method 1: Using Middleware (Recommended)
|
|
18
|
+
|
|
19
|
+
The middleware approach is the cleanest and most modern way to use Response Kit.
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
const express = require('express');
|
|
23
|
+
const response = require('response-kit');
|
|
24
|
+
|
|
25
|
+
const app = express();
|
|
26
|
+
|
|
27
|
+
// Parse JSON bodies
|
|
28
|
+
app.use(express.json());
|
|
29
|
+
|
|
30
|
+
// Attach response helpers to res object
|
|
31
|
+
app.use(response.middleware());
|
|
32
|
+
|
|
33
|
+
// Now you can use response helpers directly on res
|
|
34
|
+
app.get('/users', (req, res) => {
|
|
35
|
+
const users = [{ id: 1, name: 'John' }];
|
|
36
|
+
res.success(users, 'Users fetched successfully');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
app.listen(3000, () => {
|
|
40
|
+
console.log('Server running on port 3000');
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Method 2: Direct Function Calls (v1 Compatible)
|
|
45
|
+
|
|
46
|
+
If you prefer the original API or are migrating from v1:
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
const express = require('express');
|
|
50
|
+
const response = require('response-kit');
|
|
51
|
+
|
|
52
|
+
const app = express();
|
|
53
|
+
app.use(express.json());
|
|
54
|
+
|
|
55
|
+
app.get('/users', (req, res) => {
|
|
56
|
+
const users = [{ id: 1, name: 'John' }];
|
|
57
|
+
response.success(res, users, 'Users fetched successfully');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
app.listen(3000);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
### Global Configuration
|
|
14
68
|
|
|
15
|
-
|
|
69
|
+
Configure Response Kit once at application startup:
|
|
16
70
|
|
|
17
71
|
```js
|
|
18
|
-
const response = require(
|
|
72
|
+
const response = require('response-kit');
|
|
73
|
+
|
|
74
|
+
response.configure({
|
|
75
|
+
successKey: 'success',
|
|
76
|
+
dataKey: 'data',
|
|
77
|
+
messageKey: 'message',
|
|
78
|
+
errorKey: 'errors',
|
|
79
|
+
includeTimestamp: true,
|
|
80
|
+
includeRequestId: true,
|
|
81
|
+
includeMeta: false,
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Configuration Options
|
|
86
|
+
|
|
87
|
+
| Option | Type | Default | Description |
|
|
88
|
+
|--------|------|---------|-------------|
|
|
89
|
+
| `successKey` | string | `'success'` | Key name for success status |
|
|
90
|
+
| `dataKey` | string | `'data'` | Key name for response data |
|
|
91
|
+
| `messageKey` | string | `'message'` | Key name for messages |
|
|
92
|
+
| `errorKey` | string | `'errors'` | Key name for error details |
|
|
93
|
+
| `includeTimestamp` | boolean | `false` | Add ISO timestamp to responses |
|
|
94
|
+
| `includeRequestId` | boolean | `false` | Add request ID to responses |
|
|
95
|
+
| `includeMeta` | boolean | `false` | Add request metadata (method, path) |
|
|
96
|
+
| `timestampKey` | string | `'timestamp'` | Key name for timestamp |
|
|
97
|
+
| `requestIdKey` | string | `'requestId'` | Key name for request ID |
|
|
98
|
+
| `metaKey` | string | `'meta'` | Key name for metadata |
|
|
99
|
+
|
|
100
|
+
### Example with Custom Keys
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
response.configure({
|
|
104
|
+
successKey: 'status',
|
|
105
|
+
dataKey: 'result',
|
|
106
|
+
messageKey: 'msg',
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Response output:
|
|
110
|
+
// {
|
|
111
|
+
// "status": true,
|
|
112
|
+
// "msg": "Success",
|
|
113
|
+
// "result": { ... }
|
|
114
|
+
// }
|
|
19
115
|
```
|
|
20
116
|
|
|
21
|
-
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Using the Middleware
|
|
120
|
+
|
|
121
|
+
### Basic Usage
|
|
22
122
|
|
|
23
123
|
```js
|
|
24
|
-
|
|
124
|
+
const express = require('express');
|
|
125
|
+
const response = require('response-kit');
|
|
126
|
+
|
|
127
|
+
const app = express();
|
|
128
|
+
|
|
129
|
+
// Apply middleware globally
|
|
130
|
+
app.use(response.middleware());
|
|
131
|
+
|
|
132
|
+
// All routes now have enhanced res object
|
|
133
|
+
app.get('/api/status', (req, res) => {
|
|
134
|
+
res.success({ status: 'healthy' }, 'API is running');
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
app.get('/api/error', (req, res) => {
|
|
138
|
+
res.badRequest('Invalid request');
|
|
139
|
+
});
|
|
25
140
|
```
|
|
26
141
|
|
|
142
|
+
### Available Methods
|
|
143
|
+
|
|
144
|
+
After applying middleware, these methods are available on `res`:
|
|
145
|
+
|
|
146
|
+
**Success Responses:**
|
|
147
|
+
- `res.success(data, message, statusCode)`
|
|
148
|
+
- `res.created(data, message)`
|
|
149
|
+
|
|
150
|
+
**Error Responses:**
|
|
151
|
+
- `res.badRequest(message)`
|
|
152
|
+
- `res.unauthorized(message)`
|
|
153
|
+
- `res.forbidden(message)`
|
|
154
|
+
- `res.notFound(message)`
|
|
155
|
+
- `res.conflict(message)`
|
|
156
|
+
- `res.internalError(message)`
|
|
157
|
+
|
|
158
|
+
**Special Responses:**
|
|
159
|
+
- `res.validationError(errors, message)`
|
|
160
|
+
- `res.paginate(data, page, limit, total)`
|
|
161
|
+
|
|
27
162
|
---
|
|
28
163
|
|
|
29
|
-
##
|
|
164
|
+
## Using Async Handler
|
|
165
|
+
|
|
166
|
+
The async handler eliminates the need for repetitive try-catch blocks.
|
|
167
|
+
|
|
168
|
+
### Without Async Handler
|
|
169
|
+
|
|
170
|
+
```js
|
|
171
|
+
app.get('/users/:id', async (req, res) => {
|
|
172
|
+
try {
|
|
173
|
+
const user = await User.findById(req.params.id);
|
|
174
|
+
|
|
175
|
+
if (!user) {
|
|
176
|
+
return res.notFound('User not found');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return res.success(user);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
return res.internalError(error.message);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### With Async Handler
|
|
30
187
|
|
|
31
188
|
```js
|
|
32
|
-
|
|
33
|
-
const
|
|
189
|
+
app.get('/users/:id', response.asyncHandler(async (req, res) => {
|
|
190
|
+
const user = await User.findById(req.params.id);
|
|
191
|
+
|
|
192
|
+
if (!user) {
|
|
193
|
+
return res.notFound('User not found');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return res.success(user);
|
|
197
|
+
}));
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Error Handling with Async Handler
|
|
201
|
+
|
|
202
|
+
The async handler automatically catches errors and passes them to Express error handling middleware:
|
|
203
|
+
|
|
204
|
+
```js
|
|
205
|
+
const express = require('express');
|
|
206
|
+
const response = require('response-kit');
|
|
34
207
|
|
|
35
208
|
const app = express();
|
|
36
209
|
|
|
37
|
-
app.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
210
|
+
app.use(response.middleware());
|
|
211
|
+
|
|
212
|
+
// Routes with async handler
|
|
213
|
+
app.get('/users', response.asyncHandler(async (req, res) => {
|
|
214
|
+
const users = await User.find(); // Any error here is caught
|
|
215
|
+
res.success(users);
|
|
216
|
+
}));
|
|
217
|
+
|
|
218
|
+
// Global error handler
|
|
219
|
+
app.use((err, req, res, next) => {
|
|
220
|
+
console.error(err.stack);
|
|
221
|
+
res.internalError(err.message || 'Something went wrong');
|
|
45
222
|
});
|
|
46
223
|
|
|
47
|
-
app.listen(
|
|
224
|
+
app.listen(3000);
|
|
48
225
|
```
|
|
49
226
|
|
|
50
227
|
---
|
|
51
228
|
|
|
52
|
-
##
|
|
229
|
+
## Complete Example
|
|
53
230
|
|
|
54
|
-
|
|
55
|
-
|
|
231
|
+
Here's a complete example showing all features:
|
|
232
|
+
|
|
233
|
+
```js
|
|
234
|
+
const express = require('express');
|
|
235
|
+
const response = require('response-kit');
|
|
236
|
+
|
|
237
|
+
const app = express();
|
|
238
|
+
|
|
239
|
+
// Middleware
|
|
240
|
+
app.use(express.json());
|
|
241
|
+
app.use(response.middleware());
|
|
242
|
+
|
|
243
|
+
// Configuration
|
|
244
|
+
response.configure({
|
|
245
|
+
includeTimestamp: true,
|
|
246
|
+
includeRequestId: true,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// Mock database
|
|
250
|
+
const users = [
|
|
251
|
+
{ id: 1, name: 'John Doe', email: 'john@example.com' },
|
|
252
|
+
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' },
|
|
253
|
+
];
|
|
254
|
+
|
|
255
|
+
// Get all users
|
|
256
|
+
app.get('/users', (req, res) => {
|
|
257
|
+
res.success(users, 'Users fetched successfully');
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// Get user by ID
|
|
261
|
+
app.get('/users/:id', response.asyncHandler(async (req, res) => {
|
|
262
|
+
const user = users.find(u => u.id === parseInt(req.params.id));
|
|
263
|
+
|
|
264
|
+
if (!user) {
|
|
265
|
+
return res.notFound('User not found');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
res.success(user, 'User found');
|
|
269
|
+
}));
|
|
270
|
+
|
|
271
|
+
// Create user
|
|
272
|
+
app.post('/users', response.asyncHandler(async (req, res) => {
|
|
273
|
+
const { name, email } = req.body;
|
|
274
|
+
|
|
275
|
+
// Validation
|
|
276
|
+
if (!name || !email) {
|
|
277
|
+
return res.validationError({
|
|
278
|
+
name: !name ? 'Name is required' : undefined,
|
|
279
|
+
email: !email ? 'Email is required' : undefined,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Check for existing email
|
|
284
|
+
const existing = users.find(u => u.email === email);
|
|
285
|
+
if (existing) {
|
|
286
|
+
return res.conflict('Email already exists');
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Create user
|
|
290
|
+
const newUser = {
|
|
291
|
+
id: users.length + 1,
|
|
292
|
+
name,
|
|
293
|
+
email,
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
users.push(newUser);
|
|
297
|
+
|
|
298
|
+
res.created(newUser, 'User created successfully');
|
|
299
|
+
}));
|
|
300
|
+
|
|
301
|
+
// Update user
|
|
302
|
+
app.put('/users/:id', response.asyncHandler(async (req, res) => {
|
|
303
|
+
const user = users.find(u => u.id === parseInt(req.params.id));
|
|
304
|
+
|
|
305
|
+
if (!user) {
|
|
306
|
+
return res.notFound('User not found');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
Object.assign(user, req.body);
|
|
310
|
+
|
|
311
|
+
res.success(user, 'User updated successfully');
|
|
312
|
+
}));
|
|
313
|
+
|
|
314
|
+
// Delete user
|
|
315
|
+
app.delete('/users/:id', response.asyncHandler(async (req, res) => {
|
|
316
|
+
const index = users.findIndex(u => u.id === parseInt(req.params.id));
|
|
317
|
+
|
|
318
|
+
if (index === -1) {
|
|
319
|
+
return res.notFound('User not found');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
users.splice(index, 1);
|
|
323
|
+
|
|
324
|
+
res.success(null, 'User deleted successfully');
|
|
325
|
+
}));
|
|
326
|
+
|
|
327
|
+
// Global error handler
|
|
328
|
+
app.use((err, req, res, next) => {
|
|
329
|
+
console.error('Error:', err);
|
|
330
|
+
res.internalError(err.message || 'Internal server error');
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// 404 handler
|
|
334
|
+
app.use((req, res) => {
|
|
335
|
+
res.notFound('Route not found');
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
const PORT = process.env.PORT || 3000;
|
|
339
|
+
app.listen(PORT, () => {
|
|
340
|
+
console.log(`Server running on port ${PORT}`);
|
|
341
|
+
});
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Best Practices
|
|
347
|
+
|
|
348
|
+
### 1. Use Middleware
|
|
349
|
+
|
|
350
|
+
The middleware approach is cleaner and more maintainable:
|
|
351
|
+
|
|
352
|
+
```js
|
|
353
|
+
// ✅ Good
|
|
354
|
+
app.use(response.middleware());
|
|
355
|
+
app.get('/users', (req, res) => {
|
|
356
|
+
res.success(users);
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// ❌ Acceptable but verbose
|
|
360
|
+
app.get('/users', (req, res) => {
|
|
361
|
+
response.success(res, users);
|
|
362
|
+
});
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### 2. Configure Early
|
|
366
|
+
|
|
367
|
+
Set up configuration before defining routes:
|
|
368
|
+
|
|
369
|
+
```js
|
|
370
|
+
const response = require('response-kit');
|
|
371
|
+
|
|
372
|
+
// Configure first
|
|
373
|
+
response.configure({
|
|
374
|
+
includeTimestamp: true,
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
// Then set up app
|
|
378
|
+
const app = express();
|
|
379
|
+
app.use(response.middleware());
|
|
56
380
|
```
|
|
57
381
|
|
|
58
|
-
|
|
382
|
+
### 3. Use Async Handler
|
|
383
|
+
|
|
384
|
+
Always use async handler for async routes:
|
|
385
|
+
|
|
386
|
+
```js
|
|
387
|
+
// ✅ Good
|
|
388
|
+
app.get('/users', response.asyncHandler(async (req, res) => {
|
|
389
|
+
const users = await User.find();
|
|
390
|
+
res.success(users);
|
|
391
|
+
}));
|
|
59
392
|
|
|
60
|
-
|
|
61
|
-
|
|
393
|
+
// ❌ Risky - unhandled promise rejection
|
|
394
|
+
app.get('/users', async (req, res) => {
|
|
395
|
+
const users = await User.find();
|
|
396
|
+
res.success(users);
|
|
397
|
+
});
|
|
62
398
|
```
|
|
63
399
|
|
|
64
|
-
|
|
400
|
+
### 4. Global Error Handler
|
|
401
|
+
|
|
402
|
+
Always implement a global error handler:
|
|
65
403
|
|
|
66
|
-
```
|
|
67
|
-
{
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
404
|
+
```js
|
|
405
|
+
app.use((err, req, res, next) => {
|
|
406
|
+
console.error(err.stack);
|
|
407
|
+
res.internalError(err.message);
|
|
408
|
+
});
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### 5. Validation First
|
|
412
|
+
|
|
413
|
+
Validate input before processing:
|
|
414
|
+
|
|
415
|
+
```js
|
|
416
|
+
app.post('/users', response.asyncHandler(async (req, res) => {
|
|
417
|
+
// Validate first
|
|
418
|
+
if (!req.body.email) {
|
|
419
|
+
return res.validationError({ email: 'Email is required' });
|
|
72
420
|
}
|
|
73
|
-
|
|
421
|
+
|
|
422
|
+
// Then process
|
|
423
|
+
const user = await User.create(req.body);
|
|
424
|
+
res.created(user);
|
|
425
|
+
}));
|
|
74
426
|
```
|
|
75
427
|
|
|
76
428
|
---
|
|
77
429
|
|
|
78
430
|
## Next Steps
|
|
79
431
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
432
|
+
- Read about [Success Responses](./success-response.md)
|
|
433
|
+
- Learn about [Error Responses](./error-response.md)
|
|
434
|
+
- Explore [Pagination](./pagination.md)
|
|
435
|
+
- Check out [Complete Examples](../examples/)
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## Troubleshooting
|
|
440
|
+
|
|
441
|
+
### Middleware Not Working
|
|
442
|
+
|
|
443
|
+
Make sure you're applying middleware before your routes:
|
|
444
|
+
|
|
445
|
+
```js
|
|
446
|
+
// ✅ Correct order
|
|
447
|
+
app.use(response.middleware());
|
|
448
|
+
app.get('/users', (req, res) => res.success(users));
|
|
449
|
+
|
|
450
|
+
// ❌ Wrong order
|
|
451
|
+
app.get('/users', (req, res) => res.success(users));
|
|
452
|
+
app.use(response.middleware()); // Too late!
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### TypeScript Errors
|
|
456
|
+
|
|
457
|
+
Make sure you have the latest type definitions:
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
npm install response-kit@latest
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
Then use the extended response type:
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
import { ExtendedResponse } from 'response-kit';
|
|
467
|
+
|
|
468
|
+
app.get('/users', (req, res: ExtendedResponse) => {
|
|
469
|
+
res.success(users);
|
|
470
|
+
});
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## Support
|
|
476
|
+
|
|
477
|
+
If you encounter issues or have questions:
|
|
478
|
+
|
|
479
|
+
1. Check the [documentation](../README.md)
|
|
480
|
+
2. Look at [examples](../examples/)
|
|
481
|
+
3. Open an issue on [GitHub](https://github.com/piyush72yaduvanshi/api-response-kit/issues)
|