rpc-express-toolkit 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 ADDED
@@ -0,0 +1,796 @@
1
+ # RPC Express Toolkit
2
+
3
+ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
4
+ [![npm version](https://img.shields.io/npm/v/rpc-express-toolkit.svg)](https://www.npmjs.com/package/rpc-express-toolkit)
5
+ [![Build Status](https://github.com/n-car/rpc-express-toolkit/actions/workflows/main.yml/badge.svg)](https://github.com/n-car/rpc-express-toolkit/actions)
6
+ [![Coverage Status](https://coveralls.io/repos/github/n-car/rpc-express-toolkit/badge.svg?branch=main)](https://coveralls.io/github/n-car/rpc-express-toolkit?branch=main)
7
+
8
+ An enterprise-ready JSON-RPC 2.0 toolkit for Express.js applications with simplified APIs, structured logging, middleware system, schema validation, batch processing, and comprehensive BigInt/Date serialization support.
9
+
10
+ ## Table of Contents
11
+
12
+ - [Features](#features)
13
+ - [Installation](#installation)
14
+ - [Quick Start](#quick-start)
15
+ - [Advanced Usage](#advanced-usage)
16
+ - [Configuration Options](#configuration-options)
17
+ - [Schema Validation](#schema-validation)
18
+ - [Middleware System](#middleware-system)
19
+ - [Batch Requests](#batch-requests)
20
+ - [Structured Logging](#structured-logging)
21
+ - [Built-in Middlewares](#built-in-middlewares)
22
+ - [API Reference](#api-reference)
23
+ - [Examples](#examples)
24
+ - [Contributing](#contributing)
25
+ - [License](#license)
26
+
27
+ ## Features
28
+
29
+ ### Core Features
30
+ - **JSON-RPC 2.0 Compliance:** Fully adheres to the JSON-RPC 2.0 specification
31
+ - **Server & Client Support:** Provides both server endpoint and client classes
32
+ - **Asynchronous Support:** Handle asynchronous operations seamlessly with Promises
33
+ - **BigInt & Date Serialization:** Robust serialization/deserialization with timezone support
34
+ - **Cross-Platform:** Works in both browser and Node.js environments
35
+ - **Error Handling:** Comprehensive error responses with sanitization options
36
+
37
+ ### Enterprise Features
38
+ - **🔧 Structured Logging:** Configurable logging with multiple transports and levels
39
+ - **⚡ Middleware System:** Extensible middleware with built-in rate limiting, CORS, auth
40
+ - **✅ Schema Validation:** JSON Schema validation with Ajv and schema builder utilities
41
+ - **📦 Batch Processing:** Efficient batch request handling with concurrent processing
42
+ - **📊 Health & Metrics:** Built-in health checks and metrics endpoints
43
+ - **🔒 Security:** Method whitelisting, authentication, and error sanitization
44
+ - **🎯 Performance:** Request timing, caching support, and optimized serialization
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ npm install rpc-express-toolkit
50
+ ```
51
+
52
+ Or using yarn:
53
+
54
+ ```bash
55
+ yarn add rpc-express-toolkit
56
+ ```
57
+
58
+ **Note:** For Node.js environments older than v18, you may need to install `node-fetch` for HTTP requests:
59
+
60
+ ## Quick Start
61
+
62
+ ### Basic Setup
63
+
64
+ ```javascript
65
+ const express = require('express');
66
+ const { RpcEndpoint } = require('rpc-express-toolkit');
67
+
68
+ const app = express();
69
+ app.use(express.json());
70
+
71
+ // Context object to pass to method handlers
72
+ const context = { database: db, config: config };
73
+
74
+ // Create JSON-RPC server with clean API
75
+ const rpc = new RpcEndpoint(app, context);
76
+
77
+ // Add simple methods
78
+ rpc.addMethod('add', (req, ctx, params) => {
79
+ const { a, b } = params;
80
+ return a + b;
81
+ });
82
+
83
+ rpc.addMethod('getUser', async (req, ctx, params) => {
84
+ const { userId } = params;
85
+ const user = await ctx.database.users.findById(userId);
86
+ return user;
87
+ });
88
+
89
+ app.listen(3000, () => {
90
+ console.log('Server running on port 3000');
91
+ });
92
+ ```
93
+
94
+ ### Client Usage
95
+
96
+ ```javascript
97
+ const { RpcClient } = require('rpc-express-toolkit');
98
+
99
+ // Node.js client
100
+ const client = new RpcClient('http://localhost:3000/api');
101
+
102
+ // Make RPC calls
103
+ const result = await client.call('add', { a: 5, b: 3 });
104
+ console.log(result); // 8
105
+
106
+ // Browser client (include the client script)
107
+ const client = new RpcClient('/api');
108
+ const user = await client.call('getUser', { userId: 123 });
109
+ ```
110
+
111
+ ## Advanced Usage
112
+
113
+ ### Configuration Options
114
+
115
+ ```javascript
116
+ const rpc = new RpcEndpoint(app, context, {
117
+ endpoint: '/api',
118
+
119
+ // Logging configuration
120
+ logging: {
121
+ level: 'info',
122
+ format: 'json',
123
+ transports: ['console', 'file'],
124
+ file: {
125
+ filename: 'rpc.log',
126
+ maxsize: 10485760, // 10MB
127
+ maxFiles: 5
128
+ }
129
+ },
130
+
131
+ // Built-in middleware
132
+ cors: {
133
+ origin: ['http://localhost:3000'],
134
+ credentials: true
135
+ },
136
+
137
+ rateLimit: {
138
+ windowMs: 15 * 60 * 1000, // 15 minutes
139
+ max: 100 // limit each IP to 100 requests per windowMs
140
+ },
141
+
142
+ auth: {
143
+ required: true,
144
+ verify: (req) => {
145
+ const token = req.headers.authorization;
146
+ return verifyToken(token);
147
+ }
148
+ },
149
+
150
+ methodWhitelist: ['add', 'subtract', 'getUser'],
151
+
152
+ // Schema validation
153
+ validation: {
154
+ strict: true,
155
+ coerceTypes: true,
156
+ removeAdditional: true
157
+ },
158
+
159
+ // Feature flags
160
+ healthCheck: true,
161
+ metrics: true,
162
+ timing: true
163
+ });
164
+ ```
165
+
166
+ ### Schema Validation
167
+
168
+ ```javascript
169
+ const { SchemaBuilder, commonSchemas } = require('rpc-express-toolkit');
170
+
171
+ // Using schema builder
172
+ const addSchema = SchemaBuilder.object({
173
+ a: SchemaBuilder.number().required(),
174
+ b: SchemaBuilder.number().required()
175
+ });
176
+
177
+ // Register method with schema
178
+ rpc.addMethod('add', {
179
+ handler: (req, ctx, params) => params.a + params.b,
180
+ schema: addSchema
181
+ });
182
+
183
+ // Using common schemas
184
+ rpc.addMethod('getUser', {
185
+ handler: async (req, ctx, params) => {
186
+ return await ctx.database.users.findById(params.userId);
187
+ },
188
+ schema: {
189
+ type: 'object',
190
+ properties: {
191
+ userId: commonSchemas.positiveInteger
192
+ },
193
+ required: ['userId']
194
+ }
195
+ });
196
+ ```
197
+
198
+ ### Middleware System
199
+
200
+ ## API Reference
201
+
202
+ ### RpcEndpoint Class
203
+
204
+ #### Constructor
205
+
206
+ ```javascript
207
+ new RpcEndpoint(router, context, options)
208
+ ```
209
+
210
+ **Parameters:**
211
+ - `router` (Express.Router): Express router instance
212
+ - `context` (Object): Context object passed to method handlers
213
+ - `options` (Object|string): Configuration options or endpoint path
214
+
215
+ **Options:**
216
+ - `endpoint` (string): Endpoint path (default: '/api')
217
+ - `logging` (Object): Logging configuration
218
+ - `cors` (Object): CORS configuration
219
+ - `rateLimit` (Object): Rate limiting configuration
220
+ - `auth` (Object): Authentication configuration
221
+ - `methodWhitelist` (Array): Allowed method names
222
+ - `validation` (Object): Schema validation options
223
+ - `healthCheck` (boolean): Enable health check endpoint
224
+ - `metrics` (boolean): Enable metrics endpoint
225
+ - `timing` (boolean): Enable request timing
226
+
227
+ #### Methods
228
+
229
+ ##### `addMethod(name, handlerOrConfig, schema)`
230
+
231
+ Register a new JSON-RPC method.
232
+
233
+ ```javascript
234
+ // Simple method
235
+ rpc.addMethod('add', (req, ctx, params) => {
236
+ return params.a + params.b;
237
+ });
238
+
239
+ // Method with schema validation
240
+ rpc.addMethod('getUser', {
241
+ handler: async (req, ctx, params) => {
242
+ return await ctx.db.users.findById(params.userId);
243
+ },
244
+ schema: {
245
+ type: 'object',
246
+ properties: {
247
+ userId: { type: 'number', minimum: 1 }
248
+ },
249
+ required: ['userId']
250
+ }
251
+ });
252
+ ```
253
+
254
+ ##### `use(hook, middleware)`
255
+
256
+ Add middleware for specific execution hooks.
257
+
258
+ ```javascript
259
+ rpc.use('beforeCall', async (context) => {
260
+ // Pre-processing
261
+ return context;
262
+ });
263
+
264
+ rpc.use('afterCall', async (context) => {
265
+ // Post-processing
266
+ return context;
267
+ });
268
+
269
+ rpc.use('onError', async (context) => {
270
+ // Error handling
271
+ });
272
+ ```
273
+
274
+ ##### `removeMethod(name)`
275
+
276
+ Remove a registered method.
277
+
278
+ ```javascript
279
+ rpc.removeMethod('methodName');
280
+ ```
281
+
282
+ ##### `getMethod(name)`
283
+
284
+ Get method configuration.
285
+
286
+ ```javascript
287
+ const config = rpc.getMethod('methodName');
288
+ ```
289
+
290
+ ##### `listMethods()`
291
+
292
+ List all registered methods.
293
+
294
+ ```javascript
295
+ const methods = rpc.listMethods();
296
+ ```
297
+
298
+ ##### `getMetrics()`
299
+
300
+ Get current metrics data.
301
+
302
+ ```javascript
303
+ const metrics = rpc.getMetrics();
304
+ ```
305
+
306
+ #### Properties
307
+
308
+ - `endpoint`: The endpoint path
309
+ - `methods`: All registered methods
310
+ - `logger`: Logger instance
311
+ - `middleware`: Middleware manager
312
+ - `validator`: Schema validator
313
+
314
+ ### RpcClient Class
315
+
316
+ #### Constructor
317
+
318
+ ```javascript
319
+ new RpcClient(baseUrl, options)
320
+ ```
321
+
322
+ #### Methods
323
+
324
+ ##### `call(method, params, options)`
325
+
326
+ Make a single RPC call.
327
+
328
+ ```javascript
329
+ const result = await client.call('add', { a: 1, b: 2 });
330
+ ```
331
+
332
+ ##### `batch(requests)`
333
+
334
+ Make batch RPC calls.
335
+
336
+ ```javascript
337
+ const results = await client.batch([
338
+ { method: 'add', params: { a: 1, b: 2 } },
339
+ { method: 'subtract', params: { a: 5, b: 3 } }
340
+ ]);
341
+ ```
342
+
343
+ ##### `notify(method, params)`
344
+
345
+ Send notification (no response expected).
346
+
347
+ ```javascript
348
+ await client.notify('logEvent', { event: 'user_login' });
349
+ ```
350
+
351
+ ### Logger Class
352
+
353
+ Structured logging with configurable transports and levels.
354
+
355
+ ```javascript
356
+ const logger = new Logger({
357
+ level: 'info',
358
+ format: 'json',
359
+ transports: ['console', 'file']
360
+ });
361
+
362
+ logger.info('Message', { key: 'value' });
363
+ logger.error('Error', { error: err.message });
364
+ ```
365
+
366
+ ### SchemaValidator Class
367
+
368
+ JSON Schema validation with Ajv.
369
+
370
+ ```javascript
371
+ const validator = new SchemaValidator({
372
+ strict: true,
373
+ coerceTypes: true
374
+ });
375
+
376
+ const result = validator.validate(data, schema);
377
+ ```
378
+
379
+ ### SchemaBuilder
380
+
381
+ Utility for building JSON schemas.
382
+
383
+ ```javascript
384
+ const schema = SchemaBuilder.object({
385
+ name: SchemaBuilder.string().required(),
386
+ age: SchemaBuilder.number().min(0).max(150),
387
+ email: SchemaBuilder.string().format('email')
388
+ });
389
+ ```
390
+
391
+ ### BatchHandler
392
+
393
+ Handles batch request processing with concurrency control.
394
+
395
+ ```javascript
396
+ const batchHandler = new BatchHandler(endpoint, {
397
+ maxConcurrency: 10,
398
+ timeout: 30000
399
+ });
400
+ ```
401
+
402
+ ## Examples
403
+
404
+ ### Enterprise Configuration
405
+
406
+ ```javascript
407
+ const express = require('express');
408
+ const { RpcEndpoint, SchemaBuilder } = require('rpc-express-toolkit');
409
+
410
+ const app = express();
411
+ app.use(express.json());
412
+
413
+ const rpc = new RpcEndpoint(app, { db, config }, {
414
+ endpoint: '/api/v1',
415
+ logging: {
416
+ level: 'info',
417
+ format: 'json',
418
+ transports: ['console', 'file'],
419
+ file: { filename: 'api.log' }
420
+ },
421
+ cors: {
422
+ origin: process.env.ALLOWED_ORIGINS?.split(',') || ['http://localhost:3000'],
423
+ credentials: true
424
+ },
425
+ rateLimit: {
426
+ windowMs: 15 * 60 * 1000,
427
+ max: 100
428
+ },
429
+ auth: {
430
+ required: true,
431
+ verify: async (req) => {
432
+ const token = req.headers.authorization?.replace('Bearer ', '');
433
+ return await verifyJWT(token);
434
+ }
435
+ },
436
+ validation: {
437
+ strict: true,
438
+ coerceTypes: true
439
+ },
440
+ healthCheck: true,
441
+ metrics: true
442
+ });
443
+
444
+ // Add methods with validation
445
+ rpc.addMethod('createUser', {
446
+ handler: async (req, ctx, params) => {
447
+ const user = await ctx.db.users.create(params);
448
+ return { id: user.id, message: 'User created successfully' };
449
+ },
450
+ schema: SchemaBuilder.object({
451
+ name: SchemaBuilder.string().min(1).max(100).required(),
452
+ email: SchemaBuilder.string().format('email').required(),
453
+ age: SchemaBuilder.number().min(0).max(150).optional()
454
+ })
455
+ });
456
+
457
+ app.listen(3000);
458
+ ```
459
+
460
+ ### BigInt and Date Handling
461
+
462
+ ```javascript
463
+ // BigInt serialization
464
+ rpc.addMethod('getBigNumber', () => {
465
+ return BigInt('9007199254740991123456789'); // Automatically serialized to string
466
+ });
467
+
468
+ // Date serialization
469
+ rpc.addMethod('getCurrentTime', () => {
470
+ return new Date(); // Automatically serialized to ISO string
471
+ });
472
+
473
+ // Client receives properly typed data
474
+ const client = new RpcClient('http://localhost:3000/api');
475
+ const bigNum = await client.call('getBigNumber'); // Returns BigInt
476
+ const date = await client.call('getCurrentTime'); // Returns Date object
477
+ ```
478
+
479
+ ### Error Handling
480
+
481
+ ```javascript
482
+ rpc.addMethod('mayFail', (req, ctx, params) => {
483
+ if (params.shouldFail) {
484
+ const error = new Error('Something went wrong');
485
+ error.code = -32001; // Custom error code
486
+ error.data = { details: 'Additional error info' };
487
+ throw error;
488
+ }
489
+ return 'success';
490
+ });
491
+
492
+ // Client error handling
493
+ try {
494
+ await client.call('mayFail', { shouldFail: true });
495
+ } catch (error) {
496
+ console.log(error.code); // -32001
497
+ console.log(error.message); // 'Something went wrong'
498
+ console.log(error.data); // { details: 'Additional error info' }
499
+ }
500
+ ```
501
+ userId: 123,
502
+ action: 'login',
503
+ ip: req.ip
504
+ });
505
+
506
+ logger.error('Database error', {
507
+ error: err.message,
508
+ query: 'SELECT * FROM users',
509
+ duration: 150
510
+ });
511
+
512
+ // RPC calls are automatically logged
513
+ // [2024-01-01T10:00:00.000Z] INFO: RPC call - {"method":"getUser","params":{"userId":123},"id":"req-123","ip":"192.168.1.1"}
514
+ // [2024-01-01T10:00:00.050Z] INFO: RPC success - {"method":"getUser","id":"req-123","duration":50,"resultSize":245}
515
+ ```
516
+
517
+ ### Built-in Middlewares
518
+
519
+ ```javascript
520
+ const { builtInMiddlewares } = require('rpc-express-toolkit');
521
+
522
+ // Rate limiting
523
+ rpc.use('beforeCall', builtInMiddlewares.rateLimit({
524
+ windowMs: 15 * 60 * 1000, // 15 minutes
525
+ max: 100, // limit each IP to 100 requests per windowMs
526
+ message: 'Too many requests from this IP'
527
+ }));
528
+
529
+ // CORS
530
+ rpc.use('beforeCall', builtInMiddlewares.cors({
531
+ origin: ['http://localhost:3000', 'https://myapp.com'],
532
+ credentials: true,
533
+ methods: ['POST']
534
+ }));
535
+
536
+ // Authentication
537
+ rpc.use('beforeCall', builtInMiddlewares.auth({
538
+ required: true,
539
+ verify: async (req) => {
540
+ const token = req.headers.authorization?.replace('Bearer ', '');
541
+ return await verifyJWT(token);
542
+ },
543
+ onError: (req, error) => {
544
+ console.log('Auth failed:', error.message);
545
+ }
546
+ }));
547
+
548
+ // Method whitelisting
549
+ rpc.use('beforeCall', builtInMiddlewares.methodWhitelist([
550
+ 'add', 'subtract', 'getUser', 'updateUser'
551
+ ]));
552
+
553
+ // Request timing
554
+ rpc.use('beforeCall', builtInMiddlewares.timing());
555
+ ```
556
+ if (!token || !isValidToken(token)) { // Replace `isValidToken` with your validation logic
557
+ throw new Error('Invalid or missing token');
558
+ }
559
+ return 'OK';
560
+ });
561
+
562
+ // Example token validation function (replace with your actual logic)
563
+ function isValidToken(token) {
564
+ // Simple example: Check if the token matches a predefined value
565
+ const expectedToken = 'my-secret-token'; // Replace with your actual token handling logic
566
+ return token === expectedToken;
567
+ }
568
+
569
+ // Start the server
570
+ const PORT = process.env.PORT || 3000;
571
+ app.listen(PORT, () => {
572
+ console.log(`Server is running on port ${PORT}`);
573
+ });
574
+ ```
575
+
576
+ ### Adding Methods
577
+
578
+ You can add RPC methods using the `addMethod` function. Each method receives the `context` and `params` as arguments.
579
+
580
+ ```javascript
581
+ // Synchronous method
582
+ rpc.addMethod('multiply', (req, ctx, params) => {
583
+ const { a, b } = params;
584
+ return a * b;
585
+ });
586
+
587
+ // Asynchronous method
588
+ rpc.addMethod('divide', async (req, ctx, params) => {
589
+ const { a, b } = params;
590
+ if (b === 0) {
591
+ throw new Error('Division by zero');
592
+ }
593
+ // Simulate async operation
594
+ return Promise.resolve(a / b);
595
+ });
596
+ ```
597
+
598
+ ## API
599
+
600
+ ### RpcEndpoint Class
601
+
602
+ A class to handle JSON-RPC 2.0 requests in Express.js applications.
603
+
604
+ #### Constructor
605
+
606
+ ```javascript
607
+ new RpcEndpoint(router, context, endpoint = '/api')
608
+ ```
609
+
610
+ - **router**: *(Express.Router)* - The Express router to attach the endpoint to.
611
+ - **context**: *(Object)* - The context object to pass to the method handlers.
612
+ - **endpoint** *(optional)*: *(string)* - The endpoint path (default is `/api`).
613
+
614
+ #### addMethod
615
+
616
+ ```javascript
617
+ addMethod(name, handler)
618
+ ```
619
+
620
+ - **name**: *(string)* - The name of the RPC method.
621
+ - **handler**: *(Function)* - The function that handles the method. Receives `req` (the Request object) `context` and `params` as arguments.
622
+
623
+ ```javascript
624
+ (req, context, params) => { /* ... */ }
625
+ ```
626
+
627
+ #### Properties
628
+
629
+ - **endpoint**: *(string)* - Returns the endpoint path.
630
+ - **methods**: *(Object)* - Returns the registered methods.
631
+
632
+ #### reply
633
+
634
+ ```javascript
635
+ reply(res, { id, result, error })
636
+ ```
637
+
638
+ - **res**: *(Express.Response)* - The Express response object.
639
+ - **responsePayload**: *(Object)* - The JSON-RPC response payload.
640
+
641
+ ```javascript
642
+ {
643
+ id: string | number | null,
644
+ result: any,
645
+ error: {
646
+ code: number,
647
+ message: string,
648
+ data?: any
649
+ }
650
+ }
651
+ ```
652
+
653
+ #### serializeBigInts
654
+
655
+ ```javascript
656
+ serializeBigInts(value)
657
+ ```
658
+
659
+ - **value**: *(any)* - The value to serialize.
660
+ - **returns**: *(any)* - The serialized value with `BigInt` converted to strings.
661
+
662
+ Recursively converts `BigInt` values to strings to ensure JSON serialization compatibility.
663
+
664
+ ## Examples
665
+
666
+ Check out the [examples](./examples) directory for more usage examples.
667
+
668
+ ### Example: Complete Express Server Integration
669
+
670
+ ```javascript
671
+ const express = require('express');
672
+ const { RpcEndpoint } = require('rpc-express-toolkit');
673
+
674
+ const app = express();
675
+
676
+ app.use(express.json());
677
+
678
+ const context = { user: 'admin' };
679
+
680
+ // Attach to the app router at POST /api endpoint
681
+ const rpc = new RpcEndpoint(app, context);
682
+
683
+ rpc.addMethod('greet', (req, ctx, params) => {
684
+ const { name } = params;
685
+ return `Hello, ${name}!`;
686
+ });
687
+
688
+ rpc.addMethod('getTime', () => {
689
+ return new Date().toISOString();
690
+ });
691
+
692
+ const PORT = 3000;
693
+ app.listen(PORT, () => {
694
+ console.log(`Server listening on port ${PORT}`);
695
+ });
696
+ ```
697
+
698
+ ## Contributing
699
+
700
+ Contributions are welcome! Please feel free to submit a Pull Request.
701
+
702
+ ### Development Setup
703
+
704
+ 1. Fork the repository
705
+ 2. Clone your fork: `git clone https://github.com/yourusername/rpc-express-toolkit.git`
706
+ 3. Install dependencies: `npm install`
707
+ 4. Run tests: `npm test`
708
+ 5. Run linting: `npm run lint`
709
+
710
+ ### Running Tests
711
+
712
+ ```bash
713
+ npm test # Run all tests
714
+ npm run test:watch # Run tests in watch mode
715
+ npm run test:coverage # Run tests with coverage report
716
+ ```
717
+
718
+ ### Code Style
719
+
720
+ This project uses ESLint and Prettier for code formatting. Run `npm run lint` to check code style.
721
+
722
+ ## Security
723
+
724
+ ### Vulnerability Reporting
725
+
726
+ If you discover a security vulnerability, please send an email to security@example.com. All security vulnerabilities will be promptly addressed.
727
+
728
+ ### Best Practices
729
+
730
+ - Always validate input parameters using schema validation
731
+ - Use authentication middleware for sensitive operations
732
+ - Enable rate limiting to prevent abuse
733
+ - Sanitize error messages in production environments
734
+ - Use HTTPS in production
735
+ - Implement proper logging for audit trails
736
+
737
+ ## Performance
738
+
739
+ ### Optimization Tips
740
+
741
+ - Use batch requests for multiple operations
742
+ - Implement caching where appropriate
743
+ - Use connection pooling for database operations
744
+ - Monitor metrics and logs for performance bottlenecks
745
+ - Use clustering for high-load applications
746
+
747
+ ### Benchmarks
748
+
749
+ Performance benchmarks on a typical server setup:
750
+
751
+ - Single request: ~1-2ms overhead
752
+ - Batch request (10 items): ~5-10ms total
753
+ - Memory usage: ~50MB for 10,000 concurrent connections
754
+ - Throughput: ~5,000 requests/second
755
+
756
+ ## License
757
+
758
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
759
+
760
+ ## Changelog
761
+
762
+ ### v2.0.0 (Enterprise Edition)
763
+
764
+ - ✨ **BREAKING**: Clean API with `RpcEndpoint` and `RpcClient` classes (100% backward compatible)
765
+ - ✨ **BREAKING**: Renamed package to `rpc-express-toolkit` for better clarity
766
+ - ✨ Added structured logging with configurable transports
767
+ - ✨ Implemented middleware system with built-in middlewares
768
+ - ✨ Added schema validation with Ajv and schema builder
769
+ - ✨ Implemented batch request processing
770
+ - ✨ Added health check and metrics endpoints
771
+ - ✨ Enhanced BigInt/Date serialization with timezone support
772
+ - ✨ Added authentication and authorization middleware
773
+ - ✨ Implemented rate limiting and CORS support
774
+ - ✨ Added method whitelisting and security features
775
+ - ✨ Clean API: `RpcEndpoint`/`RpcClient` classes
776
+ - 🔧 Improved error handling and sanitization
777
+ - 🔧 Enhanced client with batch and notification support
778
+ - 🔧 Added comprehensive test coverage
779
+ - 📚 Updated documentation with enterprise features
780
+
781
+ ## Support
782
+
783
+ - 📖 [Documentation](https://github.com/n-car/rpc-express-toolkit/wiki)
784
+ - 🐛 [Issue Tracker](https://github.com/n-car/rpc-express-toolkit/issues)
785
+ - 💬 [Discussions](https://github.com/n-car/rpc-express-toolkit/discussions)
786
+
787
+ ## Acknowledgments
788
+
789
+ - JSON-RPC 2.0 Specification
790
+ - Express.js community
791
+ - Ajv JSON Schema validator
792
+ - All contributors and users
793
+
794
+ ---
795
+
796
+ Made with ❤️ by n-car