microstream-client v1.1.0
MicroStream Client SDK π
The client library for Microstream, a lightweight, real-time communication library for microservices. Replace REST/gRPC with WebSockets for event-driven messaging. Simplifies inter-service communication with a request-response pattern and automatic reconnection.
Author: Arijit Banerjee
License: MIT
Table of Contents π
- Features β¨
- How Does It Work? π
- Installation π οΈ
- Usage π
- Configuration Options βοΈ
- Log Levels π
- Error Handling π¨
- MicroStream Hub π’
- Author π¨βπ»
- Contributing π€
- License π
Features β¨
- π Real-time inter-service communication using WebSockets.
- β‘ Synchronous request-response pattern without HTTP overhead.
- π Auto-discovery and connection management.
- π Configurable logging for better observability.
- π’ Central WebSocket server for real-time communication between microservices (provided by the hub).
- π Service discovery and registration (provided by the hub).
- π‘ Request routing and response handling (provided by the hub).
- β€οΈ Heartbeat mechanism to detect and remove inactive services (provided by the hub).
How Does It Work? π
MicroStream simplifies communication between microservices using a centralized hub-and-spoke architecture, also known as a star network. In this model, the MicroStream Hub acts as the central communication point, and your microservices, equipped with the MicroStream Client, connect to the Hub and communicate through it.
Here's how it works:
π The Star Network Concept
Imagine a star:
- The center of the star is the MicroStream Hub.
- The points of the star are your microservices (each equipped with the MicroStream Client).
In this setup:
- The Hub acts as the central communication point.
- Services (nodes) connect to the Hub and communicate through it, not directly with each other.
π How It Works in Practice
Service Registration:
- Each microservice connects to the Hub using the MicroStream Client.
- The Hub automatically detects and registers the service.
Request-Response Communication in Real-Time:
Auto-Discovery:
- Once connected, the Hub keeps track of all connected services, so you donβt need to manually configure connections between services. However, you still need to specify the target service and method when sending a request.
Heartbeat Mechanism:
β¨ Why Choose MicroStream?
MicroStream is designed to make microservice communication simple, efficient, and scalable. Hereβs why youβll love it:
- Easy Setup: Minimal configuration required to get started.
- Real-Time Request-Response Communication: Built on WebSockets for instant, reliable data exchange.
- Auto-Service-Management: Once connected, the Hub keeps track of all services, simplifying network management.
- Scalable: Easily add more services without reconfiguring the network.
- Lightweight: Minimal overhead compared to traditional REST or gRPC.
- Flexible: Works seamlessly with any microservice architecture.
Installation π οΈ
npm install microstream-client
Usage π
const { MicrostreamClient } = require("microstream-client");
// Create a new MicrostreamClient instance with the necessary configuration
const client = new MicrostreamClient({
hubUrl: "http://localhost:3000", // URL of the Microstream Hub
serviceName: "auth-service", // Name of your service - it has to be unique
logLevel: "debug", // Enable debug logs
});
// Register a handler for incoming requests for event 'authenticate'
client.onRequest("authenticate", (data) => {
console.log("Received authentication request:", data);
return { success: true, token: "sample-token" }; // Respond to the request
});
// Register another handler for incoming request for another event
client.onRequest("another-event", (data) => {
console.log("Received another-event request:", data);
return { success: true, data: "sample-data" }; // Respond to the request
});
// Send a request to 'jwt-service' and handle the response
try {
const response = await client.sendRequest("jwt-service", "generate_jwt", {
userID: 123,
});
console.log("Received response:", response);
} catch (error) {
console.log("Error:", error.message);
}
// Send a request to 'profile-service' and handle the response
try {
const response = await client.sendRequest(
"profile-service",
"fetch-profile-by-userID",
{ userID: 123 }
);
console.log("Received response:", response);
} catch (error) {
console.log("Error:", error.message);
}
Explanation π¨π»βπ«
- Configuration: The
MicrostreamClient
is configured with the URL of the Microstream Hub, the unique registration name of your service, and the log level. - Registering Handlers: The
onRequest
method is used to register a handler for incoming requests. In this example, handlers respond to "authenticate" and "another-event" events.- Parameters:
event
: The event name to listen for.handler
: The function to handle the request. It receives the request data and returns the response.
- Parameters:
- Sending Requests: The
sendRequest
method is used to send a request to another service. In this example, requests are sent to the "jwt-service" to generate a JWT and to the "profile-service" to fetch a profile by user ID.- Parameters:
targetService
: The name of the target service.event
: The event name to trigger on the target service.data
: Optional data to send with the request.
- Returns: A promise that resolves with the response from the target service.
- Error Handling: The
sendRequest
method is wrapped in a try-catch block to handle any errors that may occur during the request. For example, if a request is sent to an invalid service, the Hub will respond with an error, which will be received by the client and thrown accordingly. The catch block will catch the error, and the user can display it using theerror.message
property.
- Parameters:
Configuration Options βοΈ
MicrostreamClientOptions
hubUrl
: URL of the Microstream Hub.serviceName
: A Unique Service Registation Name of the service connecting to the hub.timeout
: Timeout for requests in milliseconds (default: 5000).heartbeatInterval
: Interval for sending heartbeats in milliseconds (default: 5000).logLevel
: Log level for the client (default: "info").
Important Notes π
- Service names must be unique across your entire system. The Hub will reject any connection attempts from services trying to register with an already registered name.
- If your service attempts to connect with a name that's already registered:
- The connection will be rejected
- An error will be thrown with code
DUPLICATE_SERVICE_REGISTRATION
- The process will automatically terminate to prevent conflicts
Log Levels π
debug
: Log everything (useful for development).info
: Log info, warnings, and errors.warn
: Log warnings and errors.error
: Log only errors.silent
: Disable all logs.
Error Handling π¨
MicroStream Client implements standardized error handling using a CustomError
class. All errors follow a consistent structure to help with error management and debugging.
Error Structure π
{
code: string; // Error identification code
message: string; // Human readable error message
errorData?: any; // Optional contextual data
}
Standard Error Codes π
The Client may throw the following error types:
Error Code | Description |
---|---|
INTERNAL_SERVER_ERROR | Occurs when an event handler fails during execution |
EVENT_NOT_FOUND | Thrown when no handler is registered for the requested event |
REQUEST_TIMEOUT | Occurs when a request exceeds the configured timeout period |
DUPLICATE_SERVICE_REGISTRATION | Thrown when attempting to register a service name that's already in use |
Usage Examples π‘
// Example: Handling request errors
try {
const response = await client.sendRequest("auth-service", "validate-token", {
token: "xyz",
});
} catch (error) {
switch (error.code) {
case "REQUEST_TIMEOUT":
console.error(`Request timed out: ${error.message}`);
console.log("Request details:", error.errorData);
break;
case "EVENT_NOT_FOUND":
console.error(`Event handler not found: ${error.message}`);
break;
case "INTERNAL_SERVER_ERROR":
console.error(`Service error: ${error.message}`);
console.log("Error context:", error.errorData);
break;
}
}
Error Handling Best Practices π―
- Always wrap requests in try-catch blocks
- Check error codes for specific error handling
- Use error.errorData for additional context in debugging
- Handle REQUEST_TIMEOUT errors with appropriate retry logic
- Implement proper logging for INTERNAL_SERVER_ERROR cases
Common Error Scenarios π
Timeout Errors
- Occurs when target service doesn't respond within timeout period
- Default timeout: 5000ms (configurable via options)
- Includes target service and event details in errorData
Event Not Found
- Happens when requesting non-existent event handlers
- Includes event name and service details in errorData
- Check event name and target service configuration
Internal Server Errors
- Triggered by exceptions in event handlers
- Contains original error details in errorData
- Useful for debugging service-side issues
Service Registration Errors
- Occurs during initial connection
- Critical errors that may require process termination
- Check for duplicate service names in your network
MicroStream Hub π’
Here is the central hub for easy integration with the MicroStream Client SDK.
Author π¨βπ»
Author: Arijit Banerjee
About: Full Stack Web Developer | Cyber Security Enthusiast | Actor
Social Media: Β
Instagram
Β
LinkedIn
Β
GitHub
Β
Website
Email: arijit.codes@gmail.com
Contributing π€
We welcome contributions! Please see our CONTRIBUTING.md for guidelines on how to contribute to this project.
License π
This project is licensed under the MIT License. See the LICENSE file for details.