Migrating from v1 to v2
Strata v2 refines the API based on real-world usage of v1. While v1 is battle-tested, its API had some rough edges -- a singleton service, a built-in configuration system, and tightly coupled Redis usage. v2 cleans all of that up. Most of the internals stayed the same, but the external API has changed to be more explicit and easier to understand.
The migration is straightforward. Go through each breaking change below and apply the corresponding action.
Breaking Changes
service Singleton Replaced with StrataService Class
The exported service singleton is gone. You now construct your own StrataService instances. This makes the code easier to understand, easier to test (no singleton state leaking between tests), and allows multiple service instances in the same process.
Before:
import { service } from '@strata-js/strata';
import config from './config';
service.parseConfig(config);
await service.init('ExampleService');After:
import { StrataService } from '@strata-js/strata';
import configUtil from '@strata-js/util-config';
const config = configUtil.loadConfig('./config.yaml');
const service = new StrataService(config);
await service.start();service.id is Read-only and Auto-generated
Previously you could set the service ID in configuration. Now it's automatically generated and always unique.
Action: Remove any id settings from your service configuration.
service.name Renamed to service.serviceGroup
What was called name in v1 was actually used as the service group identifier for message routing. v2 renames it to serviceGroup to reflect this. There is now a separate read-only name property pulled from package.json for logging and informational purposes.
Before:
service:
name: MyServiceAfter:
service:
serviceGroup: MyServiceIn code:
// Before
console.log(service.name); // 'MyService' (used for routing)
// After
console.log(service.serviceGroup); // 'MyService' (used for routing)
console.log(service.name); // 'my-app' (from package.json, informational only)service.queue Removed
The queue property is gone. Queue names are now an implementation detail of the backend. Use serviceGroup for identifying your service. The responseQueue field on messages is still present but should be treated as an opaque value.
Action: Replace any usage of service.queue with service.serviceGroup.
service.init() Renamed to service.start()
The method name changed to better reflect what it does. Additionally, start() takes no arguments -- configuration is passed to the constructor.
Before:
service.init('ExampleService');
// or
service.init(config);After:
const service = new StrataService(config);
await service.start();service.parseConfig() Removed
The internal configuration parsing is gone. Configuration is passed directly to the StrataService constructor. Use your own configuration library, or use @strata-js/util-config.
Before:
import { service } from '@strata-js/strata';
import config from './config';
service.parseConfig(config);
await service.init('ExampleService');After:
import { StrataService } from '@strata-js/strata';
import configUtil from '@strata-js/util-config';
const env = process.env.ENVIRONMENT ?? 'local';
const config = configUtil.loadConfig(`./config/${ env }.yaml`);
const service = new StrataService(config);
await service.start();service.setToobusy() Renamed to service.setTooBusy()
Capital B. That's it.
Action: Find and replace setToobusy with setTooBusy.
service.client Removed
The built-in client instance on the service is gone. If your service needs to make requests to other services, create your own StrataClient:
Before:
const response = await service.client.request('OtherService', 'ctx', 'op', {});After:
import { StrataClient } from '@strata-js/strata';
const client = new StrataClient({
client: { name: 'MyServiceClient' },
backend: { type: 'redis-streams', redis: { host: 'localhost', port: 6379 } },
});
await client.start();
const response = await client.request('OtherService', 'ctx', 'op', {});Convenience Methods Removed (service.command, service.post, service.request)
These were wrappers around the internal client. Now that the client is separate, use it directly.
Action: Replace service.command(...), service.post(...), and service.request(...) with calls on your own StrataClient instance.
Configuration Utility Removed
The @strata-js/util-env-config library is deprecated. The old system required a JavaScript/TypeScript config file that could execute arbitrary code and used a tiered environment system that confused people.
v2 has no built-in configuration system. You pass a config object to the constructor, however you want to build it. We recommend @strata-js/util-config, which supports YAML, JSON, and JSON5:
Before:
import { service } from '@strata-js/strata';
import config from './config'; // JS/TS config file
service.parseConfig(config);After:
import { StrataService } from '@strata-js/strata';
import configUtil from '@strata-js/util-config';
const env = process.env.ENVIRONMENT ?? 'local';
const config = configUtil.loadConfig(`./config/${ env }.yaml`);
const service = new StrataService(config);The configuration is now exposed on both service and client instances via the config property:
console.log(service.config);
console.log(client.config);Configuration Key Changes
Several config keys have been renamed or removed:
| v1 Key | v2 Key | Notes |
|---|---|---|
service.name | service.serviceGroup | Reflects actual usage |
services | aliases | Renamed -- these are shorthands for service groups |
redis | (removed) | Moved under backend.redis |
service.queues | (removed) | Moved under backend-specific config |
backend Configuration is Required
v1 only supported Redis Streams. v2 supports multiple backends and does not have a default -- you must specify one.
Before (implicit Redis Streams):
redis:
host: localhost
port: 6379After (explicit backend):
backend:
type: redis-streams
discovery:
enabled: false
redis:
host: localhost
port: 6379
db: 0The same config as a TypeScript object:
const config = {
backend: {
type: 'redis-streams',
discovery: { enabled: false },
redis: { host: 'localhost', port: 6379, db: 0 },
},
};This is as close to v1 behavior as possible. The redis-streams backend uses the same Redis Streams implementation as v1.
StrataClient Requires Configuration in Constructor
Previously StrataClient had its own config loading methods (setConfig, parseConfig). Now configuration is passed to the constructor:
Before:
const client = new StrataClient();
client.parseConfig(config);After:
const client = new StrataClient({
client: { name: 'MyClient' },
backend: { type: 'redis-streams', redis: { host: 'localhost', port: 6379 } },
});client is No Longer an EventEmitter
The client previously emitted a commandResponse event. This has been replaced by client.command() returning the response directly.
Before:
client.on('commandResponse', (response) =>
{
console.log(response);
});
client.command('Services:MyService', 'info');After:
const response = await client.command('info', 'Services:MyService');
console.log(response);Note that the argument order for client.command() has also changed: the command name is now the first argument, and the target is the second.
client.command() Signature Changed
The method signature changed to put the command name first:
Before:
client.command('Services:MyServiceGroup', 'concurrency', { concurrency: 5 });After:
client.command('concurrency', 'Services:MyServiceGroup', { concurrency: 5 });And it now returns the response directly (a Promise<ServiceCommandResponse | undefined>) instead of requiring an event listener.
Quick Reference
| What Changed | v1 | v2 |
|---|---|---|
| Service creation | import { service } (singleton) | new StrataService(config) |
| Starting | service.init('Name') | service.start() |
| Service name config | service.name | service.serviceGroup |
| Config loading | service.parseConfig(config) | Pass to constructor |
| Config utility | @strata-js/util-env-config | @strata-js/util-config |
| Config files | JS/TS exports | YAML, JSON, or JSON5 |
| Client access | service.client | Create your own StrataClient |
| Backend config | Implicit Redis Streams | Explicit backend.type required |
| Redis config | Top-level redis key | Under backend.redis |
| Service aliases | services key | aliases key |
| Queue config | service.queues | Backend-specific config |
| Command sending | client.command(target, cmd, payload) | client.command(cmd, target, payload) |
| Command responses | Event-based (commandResponse) | Return value from command() |
| TooBusy setter | service.setToobusy() | service.setTooBusy() |
Next Steps
- Quick Start -- get a v2 service running from scratch.
- Configuration -- full v2 configuration reference.
- Backends -- the new pluggable backend system.