EasyLayer Transport SDK
A lightweight SDK for easy client-side integration with EasyLayer-based applications. Provides a unified interface for sending queries and subscribing to events over different transport protocols (HTTP, WebSocket, IPC). Designed for seamless communication with our apps.
Setup
Make sure you have Node.js (version >= 16) installed.
Install the SDK via npm or yarn:
npm install @easylayer/transport-sdk
# or
yarn add @easylayer/transport-sdk
Basic Usage
import { Client } from '@easylayer/transport-sdk';
const client = new Client({
transport: {
type: 'http',
baseUrl: '`http://localhost:3000',`
},
});
// Execute a query
const response = await client.query('generated_requestId', {
constructorName: 'GetUserQuery',
dto: {
userId: 'user123',
},
});
// Execute a streaming query (for supported transports)
for await (const item of client.streamQuery('stream_requestId', {
constructorName: 'StreamDataQuery',
dto: { limit: 100 },
})) {
console.log('Stream item:', item);
}
// Subscribe to events (if supported by transport)
const unsubscribe = client.subscribe('UserCreatedEvent', async (event) => {
console.log('User created:', event);
});
// Check connection status
console.log('Connected:', client.isConnected());
// Cleanup
await client.destroy();
NestJS Integration
The SDK can be used as a NestJS module:
import { ClientModule } from '@easylayer/transport-sdk';
@Module({
imports: [
ClientModule.forRoot({
isGlobal: true,
transport: {
type: 'http',
baseUrl: '`http://localhost:3000',`
},
}),
],
})
export class AppModule {}
// Or async configuration
@Module({
imports: [
ClientModule.forRootAsync({
isGlobal: true,
useFactory: (configService: ConfigService) => ({
transport: {
type: 'http',
baseUrl: configService.get('API_URL'),
},
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}
// Usage in service
@Injectable()
export class UserService {
constructor(private readonly client: Client) {}
async getUser(userId: string) {
return this.client.query('req-' + Date.now(), {
constructorName: 'GetUserQuery',
dto: { userId },
});
}
}
Transport API Reference
HTTP Transport
Overview
HTTP transport is used for traditional request-response communication with EasyLayer apps. All requests are sent as HTTP POST with a unified message envelope.
Configuration Options
interface HttpClientOptions {
type: 'http';
baseUrl: string; // Required: Base URL of the server
headers?: Record<string, string>; // Optional: Custom headers
maxMessageSize?: number; // Optional: Max message size (default: 100MB)
timeout?: number; // Optional: Request timeout (default: 30s)
name?: string; // Optional: Transport name for debugging
}
Configuration Example
const client = new Client({
transport: {
type: 'http',
baseUrl: '`http://localhost:3000',`
headers: {
'Authorization': 'Bearer token123',
'X-API-Version': '1.0',
},
timeout: 10000, // 10 seconds
maxMessageSize: 50 * 1024 * 1024, // 50MB
},
});
Message Format
All requests are sent as POST to the base URL with the following JSON body:
{
"action": "query",
"requestId": "generated_requestId",
"payload": {
"constructorName": "GetUserQuery",
"dto": {
"userId": "user123"
}
},
"timestamp": 1640995200000
}
Response Format
{
"action": "queryResponse",
"requestId": "generated_requestId",
"payload": {
"id": "user123",
"name": "John Doe",
"email": "john@example.com"
},
"timestamp": 1640995201000,
"responseTimestamp": 1640996201000
}
Streaming Support
For streaming queries, requests are sent to /stream
endpoint and responses are returned as NDJSON:
{"action":"streamResponse","payload":{"index":0,"data":"item1"}}
{"action":"streamResponse","payload":{"index":1,"data":"item2"}}
{"action":"streamEnd","payload":null}
API Methods
client.query(requestId, payload)
— Send a query and await responseclient.streamQuery(requestId, payload)
— Execute streaming queryclient.subscribe(constructorName, callback)
— Not supported for HTTPclient.isConnected()
— Always returnstrue
for HTTP
WebSocket Transport
Overview
WebSocket transport provides real-time bidirectional communication with EasyLayer apps. Supports queries, streaming, and event subscriptions.
Configuration Options
interface WsClientOptions {
type: 'ws';
url: string; // Required: WebSocket server URL
path?: string; // Optional: Socket.IO path (default: '/socket.io')
maxMessageSize?: number; // Optional: Max message size (default: 10MB)
timeout?: number; // Optional: Request timeout (default: 30s)
name?: string; // Optional: Transport name for debugging
}
Configuration Example
const client = new Client({
transport: {
type: 'ws',
url: '`http://localhost:3001',`
path: '/socket.io',
maxMessageSize: 5 * 1024 * 1024, // 5MB
},
});
Message Format
Messages are sent over WebSocket connection:
{
"action": "query",
"requestId": "generated_requestId",
"payload": {
"constructorName": "GetUserQuery",
"dto": { "userId": "user123" }
},
"timestamp": 1640995200000,
"responseTimestamp": 1640996201000
}
Event Subscription
// Subscribe to events
const unsubscribe = client.subscribe('UserCreatedEvent', async (event) => {
console.log('New user:', event);
});
// Unsubscribe
unsubscribe();
API Methods
client.query(requestId, payload)
— Send a query and await responseclient.streamQuery(requestId, payload)
— Execute streaming queryclient.subscribe(constructorName, callback)
— Subscribe to eventsclient.isConnected()
— Check if WebSocket is connectedclient.getSubscriptionCount(constructorName)
— Get subscription countclient.getActiveSubscriptions()
— Get all active subscriptions
IPC Transport (Node.js)
Overview
IPC transport is used for communication between Node.js processes (parent and child). Ideal for microservices architectures and process isolation.
Configuration Options
interface IpcClientOptions {
type: 'ipc';
child: ChildProcess; // Required: Child process instance
heartbeatTimeout?: number; // Optional: Heartbeat timeout (default: 30s)
maxMessageSize?: number; // Optional: Max message size (default: 1MB)
timeout?: number; // Optional: Request timeout (default: 30s)
name?: string; // Optional: Transport name for debugging
}
Configuration Example
import { fork } from 'child_process';
const child = fork('path/to/easylayer_app.js');
const client = new Client({
transport: {
type: 'ipc',
child,
heartbeatTimeout: 10000,
},
});
Message Format
Messages are sent as JSON objects through IPC:
{
"action": "query",
"requestId": "generated_request_id",
"payload": {
"constructorName": "GetUserQuery",
"dto": { "userId": "user123" }
},
"timestamp": 1640995200000,
"responseTimestamp": 1640996201000
}
Response Format
{
"action": "queryResponse",
"requestId": "generated_request_id",
"payload": {
"id": "user123",
"name": "John Doe"
},
"timestamp": 1640995201000
}
API Methods
client.query(requestId, payload)
— Send a query and await responseclient.streamQuery(requestId, payload)
— Execute streaming queryclient.subscribe(constructorName, callback)
— Subscribe to eventsclient.isConnected()
— Check if IPC channel is connectedclient.getSubscriptionCount(constructorName)
— Get subscription countclient.getActiveSubscriptions()
— Get all active subscriptions
Error Handling
Error Types
- ConnectionError — Network or connection issues
- TimeoutError — Request or connection timeouts
- MessageError — Invalid messages or server errors
- TransportInitError — Transport configuration errors
- MessageSizeError — Message size limit exceeded
- SubscriptionError — Event subscription errors