@onlineapps/service-wrapper 2.0.7 → 2.0.9

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 CHANGED
@@ -1,6 +1,19 @@
1
1
  # @onlineapps/service-wrapper
2
2
 
3
- Infrastructure wrapper that handles all workflow processing, message queue operations, and service registration for microservices.
3
+ **Collection of connectors providing all infrastructure components for business services**
4
+
5
+ Service Wrapper is a set of reusable connector components that handle message queue operations, service registration, monitoring, and health checks for microservices in a single-process architecture.
6
+
7
+ > **For complete architecture documentation, see [docs/FINAL_ARCHITECTURE.md](./docs/FINAL_ARCHITECTURE.md)**
8
+
9
+ ## Naming Convention
10
+
11
+ This package uses `@onlineapps/service-wrapper` WITHOUT any connector prefix because:
12
+ - It's the main orchestration layer, not a specific connector
13
+ - All services depend on it directly
14
+ - It aggregates all other connectors (base, infra, orch)
15
+
16
+ Directory: `/shared/connector/conn-app-service-wrapper/` (historical, kept for backward compatibility)
4
17
 
5
18
  ## Purpose
6
19
 
@@ -30,32 +43,43 @@ This package provides the infrastructure layer that sits between:
30
43
 
31
44
  ## Usage
32
45
 
33
- ### 1. Wrap Your Service
46
+ ### 1. Install Service Wrapper
47
+
48
+ ```bash
49
+ npm install @onlineapps/service-wrapper
50
+ ```
51
+
52
+ ### 2. Create Service Entry Point
34
53
 
35
54
  ```javascript
36
- const ServiceWrapper = require('@onlineapps/service-wrapper');
55
+ // index.js
37
56
  const express = require('express');
57
+ const { ServiceWrapper } = require('@onlineapps/service-wrapper');
38
58
 
39
- // Your pure business logic service
40
- const app = express();
41
- app.get('/hello', (req, res) => {
42
- res.json({ message: `Hello ${req.query.name}` });
43
- });
59
+ // Load your Express app (business logic only)
60
+ const app = require('./src/app');
44
61
 
45
- // Wrap with infrastructure
46
- const wrapper = new ServiceWrapper({
47
- service: app,
48
- serviceName: 'hello-service',
49
- openApiSpec: require('./openapi.json'),
50
- config: {
51
- rabbitmq: process.env.RABBITMQ_URL,
52
- registry: process.env.REGISTRY_URL,
53
- port: process.env.PORT || 3000
54
- }
55
- });
62
+ // Load configuration
63
+ const config = require('./conn-config/config.json');
64
+ const operations = require('./conn-config/operations.json');
56
65
 
57
- // Start wrapped service
58
- wrapper.start();
66
+ async function start() {
67
+ // 1. Start Express server
68
+ const server = app.listen(process.env.PORT || 3000);
69
+
70
+ // 2. Initialize wrapper components
71
+ const wrapper = new ServiceWrapper({
72
+ app,
73
+ server,
74
+ config,
75
+ operations
76
+ });
77
+
78
+ await wrapper.initialize();
79
+ console.log('Service ready with all infrastructure components');
80
+ }
81
+
82
+ start().catch(console.error);
59
83
  ```
60
84
 
61
85
  ### 2. Service Receives
@@ -77,25 +101,37 @@ NO infrastructure code needed in your service!
77
101
 
78
102
  ## Configuration
79
103
 
80
- ```javascript
104
+ ### operations.json
105
+ ```json
81
106
  {
82
- service: expressApp, // Your Express app
83
- serviceName: 'my-service', // Service identifier
84
- openApiSpec: {}, // OpenAPI specification
85
- config: {
86
- rabbitmq: 'amqp://...', // RabbitMQ connection
87
- registry: 'http://...', // Registry URL
88
- redis: 'redis://...', // Redis connection
89
- port: 3000, // Service port
90
- healthPath: '/health', // Health check path
91
- retryPolicy: { // Retry configuration
92
- maxRetries: 3,
93
- backoffMs: 1000
107
+ "operations": {
108
+ "operation-name": {
109
+ "description": "Operation description",
110
+ "endpoint": "/api/operation",
111
+ "method": "POST",
112
+ "input": { "name": { "type": "string", "required": true } },
113
+ "output": { "result": { "type": "string" } }
94
114
  }
95
115
  }
96
116
  }
97
117
  ```
98
118
 
119
+ ### config.json
120
+ ```json
121
+ {
122
+ "service": {
123
+ "name": "my-service",
124
+ "port": 3000
125
+ },
126
+ "wrapper": {
127
+ "mq": { "url": "${RABBITMQ_URL}" },
128
+ "registry": { "url": "${REGISTRY_URL}" },
129
+ "monitoring": { "enabled": true },
130
+ "health": { "endpoint": "/health" }
131
+ }
132
+ }
133
+ ```
134
+
99
135
  ## What This Handles
100
136
 
101
137
  ### Workflow Processing
@@ -133,12 +169,14 @@ Your service should NOT have:
133
169
  ```
134
170
  my-service/
135
171
  ├── src/
136
- │ ├── index.js # Express app (business logic only)
172
+ │ ├── app.js # Express app (business logic only)
137
173
  │ ├── routes/ # API endpoints
138
174
  │ └── services/ # Business logic
139
- ├── connector-config/
140
- └── openapi.json # API specification
141
- └── package.json # Dependencies (no @onlineapps/connector-*)
175
+ ├── conn-config/
176
+ ├── config.json # Service & wrapper configuration
177
+ └── operations.json # Operations specification
178
+ ├── index.js # Main entry point (initializes wrapper)
179
+ └── package.json # Dependencies including @onlineapps/service-wrapper
142
180
  ```
143
181
 
144
182
  ## Testing
@@ -0,0 +1,132 @@
1
+ # API Structure Standard for Microservices
2
+
3
+ ## Endpoint Structure
4
+
5
+ All microservices follow a simple, unversioned API structure.
6
+
7
+ ### URL Pattern
8
+
9
+ ```
10
+ / # Service discovery
11
+ /health # Health check
12
+ /status # Service status
13
+ /metrics # Prometheus metrics
14
+ /specification # Operations specification
15
+ /api/{operation} # Business operations
16
+ ```
17
+
18
+ ### Endpoint Categories
19
+
20
+ - **System endpoints**: Health, status, metrics, specification
21
+ - **Business endpoints** (`/api/*`): Application-specific operations
22
+
23
+ ## Standard Endpoints
24
+
25
+ ### Discovery Endpoint
26
+
27
+ **GET /**
28
+ ```json
29
+ {
30
+ "service": "service-name",
31
+ "version": "1.0.0",
32
+ "description": "Service description",
33
+ "specification": "/specification",
34
+ "health": "/health",
35
+ "status": "/status"
36
+ }
37
+ ```
38
+
39
+ ### System Endpoints
40
+
41
+ | Endpoint | Purpose | Response |
42
+ |----------|---------|----------|
43
+ | `GET /health` | Basic health check | `{"status": "healthy", "timestamp": "..."}` |
44
+ | `GET /status` | Detailed service status | Service metrics and dependencies |
45
+ | `GET /specification` | Operations specification | Operations JSON schema |
46
+ | `GET /metrics` | Prometheus metrics | Metrics in Prometheus format |
47
+
48
+ ### Business Endpoints
49
+
50
+ Service-specific operations under `/api/*`:
51
+ - `POST /api/create-user`
52
+ - `POST /api/process-order`
53
+ - `GET /api/get-product`
54
+
55
+ ## Implementation Guide
56
+
57
+ ### Express.js Structure
58
+
59
+ ```javascript
60
+ const express = require('express');
61
+ const app = express();
62
+
63
+ // Root endpoint - service discovery
64
+ app.get('/', (req, res) => {
65
+ res.json({
66
+ service: process.env.SERVICE_NAME,
67
+ version: require('./package.json').version,
68
+ specification: '/specification',
69
+ health: '/health',
70
+ status: '/status'
71
+ });
72
+ });
73
+
74
+ // System endpoints
75
+ app.get('/health', healthHandler);
76
+ app.get('/status', statusHandler);
77
+ app.get('/specification', specificationHandler);
78
+ app.get('/metrics', metricsHandler);
79
+
80
+ // Business endpoints under /api
81
+ app.post('/api/create-user', createUserHandler);
82
+ app.post('/api/process-order', processOrderHandler);
83
+ app.get('/api/get-product', getProductHandler);
84
+ ```
85
+
86
+ ## Configuration Structure
87
+
88
+ All service configurations are stored in `conn-config/` directory:
89
+
90
+ ```
91
+ /your-service
92
+ /conn-config
93
+ /config.json # Main configuration
94
+ /operations.json # Operations specification
95
+ /middleware.json # Middleware configuration
96
+ ```
97
+
98
+ See [Configuration Guide](./CONFIGURATION_GUIDE.md) for details.
99
+
100
+ ## Migration Guide
101
+
102
+ ### From OpenAPI to Operations
103
+
104
+ | Old | New | Purpose |
105
+ |-----|-----|------|
106
+ | `/api/v1/specification` | `/specification` | Operations schema |
107
+ | `/v1/system/health` | `/health` | Health check |
108
+ | `/v1/system/status` | `/status` | Service status |
109
+ | `/v1/{operation}` | `/api/{operation}` | Business operations |
110
+
111
+ ### Simple Migration Steps
112
+
113
+ 1. Create `operations.json` from OpenAPI
114
+ 2. Remove version prefixes from endpoints
115
+ 3. Move business endpoints under `/api`
116
+ 4. Update service discovery response
117
+
118
+ ## Testing Requirements
119
+
120
+ Tests must verify:
121
+
122
+ 1. **Discovery endpoint** returns service info and specification link
123
+ 2. **System endpoints** work correctly
124
+ 3. **Business endpoints** under `/api` process operations
125
+ 4. **Operations schema** is valid and complete
126
+
127
+ ## Benefits
128
+
129
+ 1. **Simplicity** - No version complexity
130
+ 2. **Clear structure** - System vs business separation
131
+ 3. **Direct mapping** - Operations to Cookbook steps
132
+ 4. **Lightweight** - Minimal configuration needed
@@ -0,0 +1,200 @@
1
+ # Architecture Decision: Service Wrapper vs Business Services
2
+
3
+ > **NOTE: This document describes the evolution of our thinking. For the final decision, see [FINAL_ARCHITECTURE.md](./FINAL_ARCHITECTURE.md)**
4
+
5
+ ## Executive Summary
6
+
7
+ After critical analysis, we've determined that business services should remain as standard Express applications with Service Wrapper acting as a thin MQ-to-HTTP proxy layer.
8
+
9
+ ## Business Service Requirements
10
+
11
+ ### MUST Have:
12
+ 1. **Express HTTP Server** - Full REST API capability
13
+ 2. **Own Database Connections** - Direct ORM/query access
14
+ 3. **Own Dependencies** - Complete node_modules
15
+ 4. **Standalone Operation** - Must run without wrapper
16
+ 5. **Standard Testing** - curl/Postman testable
17
+
18
+ ### Service Structure:
19
+ ```
20
+ /service-name/
21
+ /src/
22
+ app.js # Express application
23
+ /models/ # Database models
24
+ /controllers/ # HTTP controllers
25
+ /services/ # Business logic
26
+ /validators/ # Input validation
27
+ /conn-config/
28
+ operations.json # Operation definitions
29
+ config.json # Service configuration
30
+ package.json # All dependencies
31
+ ```
32
+
33
+ ### Operations Specification:
34
+ ```json
35
+ {
36
+ "operations": {
37
+ "operation-name": {
38
+ "endpoint": "/api/operation",
39
+ "method": "POST",
40
+ "input": { "schema": "..." },
41
+ "output": { "schema": "..." }
42
+ }
43
+ }
44
+ }
45
+ ```
46
+
47
+ ## Service Wrapper Responsibilities
48
+
49
+ ### Core Functions:
50
+ 1. **MQ Listener** - Consumes from RabbitMQ queues
51
+ 2. **HTTP Proxy** - Forwards to service endpoints
52
+ 3. **Service Registry** - Registers with discovery
53
+ 4. **Cookbook Router** - Routes workflow steps
54
+
55
+ ### What Wrapper Does NOT Do:
56
+ - ❌ Create HTTP server for service
57
+ - ❌ Handle business logic
58
+ - ❌ Manage database connections
59
+ - ❌ Validate business rules
60
+ - ❌ Generate responses
61
+
62
+ ### Wrapper Architecture:
63
+ ```javascript
64
+ // wrapper.js
65
+ const ServiceWrapper = require('@onlineapps/service-wrapper');
66
+
67
+ new ServiceWrapper({
68
+ serviceName: 'hello-service',
69
+ serviceUrl: 'http://localhost:3000',
70
+ mqConfig: { /* RabbitMQ settings */ },
71
+ mode: 'proxy' // Just forwards MQ→HTTP
72
+ }).start();
73
+ ```
74
+
75
+ ## Communication Flow
76
+
77
+ ```
78
+ [Cookbook Message]
79
+
80
+ [Service Wrapper]
81
+ ├─ Reads operations.json
82
+ ├─ Maps operation to endpoint
83
+ ├─ Makes HTTP call
84
+
85
+ [Business Service Express]
86
+ ├─ Handles HTTP request
87
+ ├─ Executes business logic
88
+ ├─ Returns HTTP response
89
+
90
+ [Service Wrapper]
91
+ ├─ Transforms response
92
+ └─ Sends to next queue
93
+ ```
94
+
95
+ ## Why This Architecture?
96
+
97
+ ### Separation of Concerns:
98
+ - **Business Service** = Business logic + API
99
+ - **Service Wrapper** = MQ communication only
100
+
101
+ ### Benefits:
102
+ 1. **Independence** - Services run standalone
103
+ 2. **Simplicity** - No complex handler mapping
104
+ 3. **Compatibility** - Works with existing services
105
+ 4. **Testability** - Standard HTTP testing
106
+ 5. **Flexibility** - Can swap wrapper implementations
107
+
108
+ ### Drawbacks Considered:
109
+ - Extra HTTP hop (acceptable for clarity)
110
+ - Two processes (acceptable for isolation)
111
+ - More memory (acceptable for stability)
112
+
113
+ ## Migration Path
114
+
115
+ ### For New Services:
116
+ 1. Build Express API normally
117
+ 2. Add operations.json
118
+ 3. Add wrapper.js for MQ
119
+
120
+ ### For Existing Services:
121
+ 1. Keep service unchanged
122
+ 2. Add operations.json
123
+ 3. Add wrapper.js for MQ
124
+
125
+ ### No Breaking Changes Required!
126
+
127
+ ## Decision Matrix
128
+
129
+ | Aspect | Handlers Approach | Express + Wrapper |
130
+ |--------|------------------|-------------------|
131
+ | Complexity | High | Low |
132
+ | Testing | Complex | Simple |
133
+ | Dependencies | Conflicting | Isolated |
134
+ | Database | Problematic | Natural |
135
+ | Debugging | Hard | Easy |
136
+ | **Winner** | ❌ | ✅ |
137
+
138
+ ## Final Decision
139
+
140
+ **Business services remain as Express applications.**
141
+ **Service Wrapper acts as MQ-to-HTTP proxy only.**
142
+
143
+ This provides:
144
+ - Maximum compatibility
145
+ - Minimum complexity
146
+ - Clear separation
147
+ - Easy migration
148
+
149
+ ## Implementation Guidelines
150
+
151
+ 1. **Every service has:**
152
+ - Express app with REST endpoints
153
+ - operations.json describing operations
154
+ - Optional wrapper.js for MQ integration
155
+
156
+ 2. **Service Wrapper:**
157
+ - Reads operations.json
158
+ - Listens to MQ
159
+ - Calls HTTP endpoints
160
+ - Returns responses to MQ
161
+
162
+ 3. **No direct handler execution**
163
+ - Always through HTTP
164
+ - Clear contract via operations.json
165
+ - Standard REST patterns
166
+
167
+ ## Examples
168
+
169
+ ### Hello Service:
170
+ ```javascript
171
+ // app.js - Standard Express
172
+ app.post('/api/good-day', (req, res) => {
173
+ res.json({ message: `Good day, ${req.body.name}!` });
174
+ });
175
+
176
+ // operations.json - Contract
177
+ {
178
+ "operations": {
179
+ "good-day": {
180
+ "endpoint": "/api/good-day",
181
+ "method": "POST"
182
+ }
183
+ }
184
+ }
185
+
186
+ // wrapper.js - MQ Bridge
187
+ new ServiceWrapper({
188
+ serviceUrl: 'http://localhost:33199'
189
+ }).start();
190
+ ```
191
+
192
+ ### Invoicing Service:
193
+ - Keeps all controllers, models, validators
194
+ - Adds operations.json
195
+ - Adds wrapper.js
196
+ - NO other changes needed
197
+
198
+ ## Conclusion
199
+
200
+ The architecture prioritizes **simplicity and compatibility** over theoretical purity. Services remain standard Express apps, making them easy to develop, test, and maintain. Service Wrapper provides the MQ integration layer without disrupting the service internals.