Skip to content

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:

typescript
import { service } from '@strata-js/strata';
import config from './config';

service.parseConfig(config);
await service.init('ExampleService');

After:

typescript
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:

yaml
service:
  name: MyService

After:

yaml
service:
  serviceGroup: MyService

In code:

typescript
// 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:

typescript
service.init('ExampleService');
// or
service.init(config);

After:

typescript
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:

typescript
import { service } from '@strata-js/strata';
import config from './config';

service.parseConfig(config);
await service.init('ExampleService');

After:

typescript
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:

typescript
const response = await service.client.request('OtherService', 'ctx', 'op', {});

After:

typescript
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:

typescript
import { service } from '@strata-js/strata';
import config from './config';  // JS/TS config file

service.parseConfig(config);

After:

typescript
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:

typescript
console.log(service.config);
console.log(client.config);

Configuration Key Changes

Several config keys have been renamed or removed:

v1 Keyv2 KeyNotes
service.nameservice.serviceGroupReflects actual usage
servicesaliasesRenamed -- 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):

yaml
redis:
  host: localhost
  port: 6379

After (explicit backend):

yaml
backend:
  type: redis-streams

  discovery:
    enabled: false

  redis:
    host: localhost
    port: 6379
    db: 0

The same config as a TypeScript object:

typescript
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:

typescript
const client = new StrataClient();
client.parseConfig(config);

After:

typescript
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:

typescript
client.on('commandResponse', (response) =>
{
    console.log(response);
});

client.command('Services:MyService', 'info');

After:

typescript
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:

typescript
client.command('Services:MyServiceGroup', 'concurrency', { concurrency: 5 });

After:

typescript
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 Changedv1v2
Service creationimport { service } (singleton)new StrataService(config)
Startingservice.init('Name')service.start()
Service name configservice.nameservice.serviceGroup
Config loadingservice.parseConfig(config)Pass to constructor
Config utility@strata-js/util-env-config@strata-js/util-config
Config filesJS/TS exportsYAML, JSON, or JSON5
Client accessservice.clientCreate your own StrataClient
Backend configImplicit Redis StreamsExplicit backend.type required
Redis configTop-level redis keyUnder backend.redis
Service aliasesservices keyaliases key
Queue configservice.queuesBackend-specific config
Command sendingclient.command(target, cmd, payload)client.command(cmd, target, payload)
Command responsesEvent-based (commandResponse)Return value from command()
TooBusy setterservice.setToobusy()service.setTooBusy()

Next Steps