@onlineapps/service-wrapper
v2.0.59
Published
Thin orchestration layer for microservices - delegates all infrastructure concerns to specialized connectors
Maintainers
Readme
@onlineapps/service-wrapper
Collection 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
Naming Convention
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)
Purpose
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
Key Features
- 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
Architecture
[RabbitMQ Message] → [Service Wrapper] → [Service API Call] → [Business Logic]
↑ ↑ ↑
This package operations.json Your service
Handles all Defines API Pure business
infrastructure mapping logic onlyUsage
1. Install Service Wrapper
npm install @onlineapps/service-wrapper2. Create Service Entry Point
// 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);2. Service Receives
The wrapper automatically:
- Subscribes to
{serviceName}.workflowqueue - Processes workflow messages
- Calls your API endpoints based on cookbook steps
- Routes results to next service
3. Your Service Focuses on Business Logic
Your service only needs to:
- Expose API endpoints
- Implement business logic
- Return results
NO infrastructure code needed in your service!
Configuration
Environment Variable Parsing
ServiceWrapper handles environment variable parsing directly rather than delegating to a separate connector. This design decision is based on:
- Core Responsibility - Configuration loading is fundamental to the wrapper's initialization, not a specialized concern
- Simplicity - Avoids creating a separate connector for ~20 lines of parsing logic
- Performance - Eliminates unnecessary abstraction layers for a trivial operation
- 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.
operations.json
{
"operations": {
"operation-name": {
"description": "Operation description",
"endpoint": "/api/operation",
"method": "POST",
"input": { "name": { "type": "string", "required": true } },
"output": { "result": { "type": "string" } }
}
}
}config.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
Workflow Processing
- Receives workflow messages from queue
- Validates cookbook structure
- Executes steps for this service
- Routes to next service or completion
API Mapping
- Maps cookbook steps to API calls
- Handles input/output transformation
- Manages context passing between steps
Infrastructure Concerns
- Service registration and health checks
- Message queue subscription and publishing
- Error handling and retry logic
- Dead letter queue routing
Service Requirements
Your service needs:
- Operations specification - Describes your API operations (Operations Standard)
- Express app - With business logic endpoints
- 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-wrapperTesting
The wrapper provides test utilities:
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:
- Install service-wrapper:
npm install @onlineapps/service-wrapper - Remove all direct connector imports from service code (use wrapper instead)
- Delete workflow processing files
- Wrap your Express app with ServiceWrapper
- Test that everything still works
License
PROPRIETARY - All rights reserved
