Thin orchestration layer for microservices - delegates all infrastructure concerns to specialized connectors
npm install @onlineapps/service-wrapperCollection of connectors providing all infrastructure components for business services
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.
> For complete architecture documentation, see docs/FINAL_ARCHITECTURE.md
This package uses @onlineapps/service-wrapper WITHOUT any connector prefix because:
- It's the main orchestration layer, not a specific connector
- All services depend on it directly
- It aggregates all other connectors (base, infra, orch)
Directory: /shared/connector/conn-app-service-wrapper/ (historical, kept for backward compatibility)
This package provides the infrastructure layer that sits between:
- Message Queues (RabbitMQ) and Services (business logic)
- Workflow Engine and Service APIs
- Service Registry and Service Implementation
- Automatic workflow processing - Handles cookbook execution
- Message queue integration - Subscribes to queues, routes messages
- Service registration - Auto-registers with service registry
- API-to-Cookbook mapping - Converts workflow steps to API calls
- Error handling - Retry logic, DLQ routing
- Health checks - Automatic health endpoint
```
[RabbitMQ Message] → [Service Wrapper] → [Service API Call] → [Business Logic]
↑ ↑ ↑
This package operations.json Your service
Handles all Defines API Pure business
infrastructure mapping logic only
`bash`
npm install @onlineapps/service-wrapper
`javascript
// index.js
const express = require('express');
const { ServiceWrapper } = require('@onlineapps/service-wrapper');
// Load your Express app (business logic only)
const app = require('./src/app');
// Load configuration
const config = require('./conn-config/config.json');
const operations = require('./conn-config/operations.json');
async function start() {
// 1. Start Express server
const server = app.listen(process.env.PORT || 3000);
// 2. Initialize wrapper components
const wrapper = new ServiceWrapper({
app,
server,
config,
operations
});
await wrapper.initialize();
console.log('Service ready with all infrastructure components');
}
start().catch(console.error);
`
The wrapper automatically:
- Subscribes to {serviceName}.workflow queue
- Processes workflow messages
- Calls your API endpoints based on cookbook steps
- Routes results to next service
Your service only needs to:
- Expose API endpoints
- Implement business logic
- Return results
NO infrastructure code needed in your service!
ServiceWrapper handles environment variable parsing directly rather than delegating to a separate connector. This design decision is based on:
1. Core Responsibility - Configuration loading is fundamental to the wrapper's initialization, not a specialized concern
2. Simplicity - Avoids creating a separate connector for ~20 lines of parsing logic
3. Performance - Eliminates unnecessary abstraction layers for a trivial operation
4. Universal Need - All connectors (MQ, Registry, Cache) require parsed configuration
The wrapper parses ${VAR:default} syntax in configuration files:${RABBITMQ_URL}
- - Uses environment variable, fails if not set${PORT:3000}
- - Uses environment variable, defaults to 3000 if not set${ENABLED:true}
- - Uses environment variable, defaults to true
This follows Docker/Kubernetes best practices for configuration management while keeping the wrapper architecture clean and focused.
json
{
"operations": {
"operation-name": {
"description": "Operation description",
"endpoint": "/api/operation",
"method": "POST",
"input": { "name": { "type": "string", "required": true } },
"output": { "result": { "type": "string" } }
}
}
}
`$3
`json
{
"service": {
"name": "my-service",
"port": "${PORT:3000}"
},
"wrapper": {
"mq": {
"url": "${RABBITMQ_URL:amqp://localhost:5672}",
"enabled": "${MQ_ENABLED:true}"
},
"registry": {
"url": "${REGISTRY_URL}",
"enabled": "${REGISTRY_ENABLED:false}"
},
"monitoring": {
"enabled": "${MONITORING_ENABLED:true}"
},
"health": {
"endpoint": "/health"
}
}
}
`What This Handles
$3
- Receives workflow messages from queue
- Validates cookbook structure
- Executes steps for this service
- Routes to next service or completion$3
- Maps cookbook steps to API calls
- Handles input/output transformation
- Manages context passing between steps$3
- Service registration and health checks
- Message queue subscription and publishing
- Error handling and retry logic
- Dead letter queue routingService Requirements
Your service needs:
1. Operations specification - Describes your API operations (Operations Standard)
2. Express app - With business logic endpoints
3. Configuration files - Service config and environment variables
Your service should NOT have:
- Workflow processing code
- Message queue operations
- Service registration logic
- Connector imports
Example Service Structure
`
my-service/
├── src/
│ ├── app.js # Express app (business logic only)
│ ├── routes/ # API endpoints
│ └── services/ # Business logic
├── conn-config/
│ ├── config.json # Service & wrapper configuration
│ └── operations.json # Operations specification
├── index.js # Main entry point (initializes wrapper)
└── package.json # Dependencies including @onlineapps/service-wrapper
`Testing
The wrapper provides test utilities:
`javascript
const { TestWrapper } = require('@onlineapps/service-wrapper');describe('My Service', () => {
let wrapper;
beforeAll(() => {
wrapper = new TestWrapper({
service: myApp,
mockQueues: true,
mockRegistry: true
});
});
test('processes workflow step', async () => {
const result = await wrapper.processStep({
type: 'task',
service: 'my-service',
operation: 'doSomething'
});
expect(result).toBeDefined();
});
});
`Migration from Embedded Infrastructure
If your service currently has workflow code:
1. Install service-wrapper:
npm install @onlineapps/service-wrapper`PROPRIETARY - All rights reserved