12 KiB
Migration Guide
The NATS ecosystem has grown a lot since the 2.0 release of the nats (nats.js)
client. NATS currently runs in several JavaScript runtimes: Deno, Browser, and
Node/Bun.
While the organization of the library has served developers well, there are a number of issues we would like to address going forward:
- Strict SemVer on the libraries. Any API break will signal a major version bump, this will allow you to opt-in on upgrades knowing that major version bumps may require updating your code.
- Better presentation of NATS technologies to developers that are interested in KV, ObjectStore or JetStream.
- Smaller dependencies for those that are only interested in the NATS core functionality.
- More agility and independence to each of the modules, as well as their own version.
- Easier understanding of the functionality in question, as each repository hosting the individual libraries will focus on the API provided by that library.
- Reduce framework dependency requirements where possible.
In order to satisfy those needs, the NATS JavaScript library has split into separate libraries which focus on:
- NatsCore
@nats-io/nats-core- publish/subscribe/request-reply. - JetStream
@nats-io/jetstream(depends on@nats-core) - KV
@nats-io/kv(depends on JetStream) - ObjectStore
@nats-io/obj(depends on JetStream) - Services
@nats-io/services(depends on NatsCore)
The transports have also been migrated:
@nats-io/transport-nodehas all the functionality of the originalnats.js@nats-io/transport-denohas all the functionality ofnats.denonats.wsis now part of@nats-io/nats-coreas it can be used from Deno or latest version of Node directly or any runtime that has standard W3C Websocket support.
Note that when installing @nats-io/transport-node or
@nats-io/transport-deno, the @nats-io/nats-core APIs are also made
available.
Your library selection process will start by selecting your runtime, and
importing any additional functionality you may be interested in. The
@nats-io/transport-node, @nats-io/transport-deno depend on and re-export
@nats-io/nats-core.
To use the extended functionality (JetStream, KV, ObjectStore, Services) you will need to install and import from the other libraries to access those APIs.
For example, developers that use JetStream can access it by using the functions
jetstream() and jetstreamManager() and provide their NATS connection. Note
that the NatsConnection#jetstream/Manager() APIs are no longer available.
Developers interested in KV or ObjectStore can access the resources by calling
creating a Kvm and calling create() or open() using either a
JetStreamClient or a plain NatsConnection. Note that the
JetStreamClient#views API is also no longer available.
Other add-ons such as those found in Orbit.js will require an interface
(NatsConnection, JetStreamClient, etc) reducing the complexity for packaging
these modules for cross-runtime consumption.
Changes to Clients
- Deno
- Node
- W3C Websocket - the client can be created in a compliant
runtime via the
wsconnectfunction
Changes in Nats Base Client
- QueuedIterator type incorrectly exposed a
push()operation - this operation is not public API and was removed from the interface. - The internal type
TypedSubscriptionand associated interfaces have been removed, these were supporting legacy JetStream APIs (subscribe/pullSubscribe(). If you were using these internal types to transform the types in the subscription, take a look at messagepipeline. - The utilities
JSONCodecandStringCodechave been removed, theMsgtypes and derivatives can set string or Uint8Array payloads. To read payloads as string or JSON usestring()andjson()methods on Msg or its derivatives. For publishing JSON payloads, simply specify the output ofJSON.stringify()to the publish or request operation. - NatsError was removed in favor of more descriptive types. For example, if you
make a request, the request could fail with a RequestError or TimeoutError.
The RequestError in turn will contain the
causesuch asNoRespondersError. This also means that in TypeScript, the callback signature has been relaxed to just(Error, Msg)=>void | Promise<never>. For more information see the JsDocs. - Previous versions of the client provided the enums
EventsandDebugEventsfor thetypevalues in the notification received viastatus(): AsyncIterable<Status>iterator. Starting with this release, reported status provide their own types which means that they provide richer data and are easier to use from different modules, since you can provide the string name of the type. For more information see Lifecycle and Informational and Events - Subscription#closed now resolves to void or an Error (it doesn't throw). The error is the reason why the subscription closed.
- RequestStrategy "Jitter" is now called "stall" to adopt the term used by new implementations in other clients and the RequestStrategy enum is now a type alias to simple strings "timer", "count", "stall", "sentinel".
SHA256a support type for object store has been removed. Client replaced this library with a dependency.Base64Codec,Base64UrlCodec,Base64UrlPaddedCodecsupport types for object store have been moved to @nats-io/obj.MsgCallback-(err: Error|null, msg: T) => voidhas changed to be(err: Error|null, msg:T) => void | Promise<never>to indicate that they cannot containawait. If you want to perform async handling, it must be done inside an async iterator, or outside the callback.
Changes in JetStream
To use JetStream, you must install and import @nats/jetstream.
jetStream()andjetStreamManager()functions on theNatsConnectionhave been removed. Install and import theJetStreamlibrary, and calljetstream(nc: NatsConnection)orjetstreamManager(nc: NatsConnection)- The
viewsproperty in the JetStream client has been removed - install theKVorObjectStorelibrary. jetstreamManager.listKvs()andjetstreamManager.listObjectStores()apis have been removed. Use thelist()methods provided theKvmandObjMAPIs instead.JetStreamClient#subscribe(),JetStreamClient#fetch()have been removed. Use theConsumersAPI toget()your consumer.OrderedConsumerOptions#filterSubjectschanged toOrderedConsumerOptions#filter_subjects.- Consumer.status() now returns
AsyncIterable<ConsumerStatus>instead of aPromise<AsyncIterable<ConsumerStatus>> JetStreamClient.pull()was deprecated and was removed. UseConsumer.next().- The utility function
consumerOpts()and associated functionisConsumerOptsBuilder()have been removed. Alongside of itConsumerOptsBuilderwhich was used bysubscribe()andpullSubscribe()type has also been removed. - JetStream errors are now expressed by the type
JetStreamErrorandJetStreamAPIError. Common errors such asConsumerNotFound, andStreamNotFound,JetStreamNotEnabledare subtypes of the above. For API calls where the server could return an error, these areJetStreamAPIErrorand contain all the information returned by the server. - JetStream
Stream.getMessage()will now return null if when a message not found error raises, this simplifies client usage and aligns with other APIs in the client. - MsgRequest for
Stream#getMessage()removed deprecated number argument. - For non-ordered consumers next/fetch() can will now throw/reject when heartbeats are missed.
- The
ConsumerEventsandConsumerDebugEventsenum has been removed and replaced withConsumerNotificationwhich have a discriminating fieldtype. The status objects provide a more specific API for querying those events. JsMsg.info.redeliveryCountwas renamed toJsMsg.info.deliveryCountas it tracks all delivery attempts, not just redeliveries.ConsumerCallbackFn-(m: JsMsg) => voidhas changed to be(m: JsMsg) => void | Promise<never>to indicate that they cannot containawait. If you want to perform async handling, it must be done inside an async iterator, or outside the callback.
Changes to KV
To use KV, you must install and import @nats-io/kv, and create an instance of
Kvm:
import { connect } from "@nats-io/transport-deno";
import { jetstream } from "@nats-io/jetstream";
import { Kvm } from "@nats-io/kv";
const nc = await connect();
let kvm = new Kvm(nc);
// or create a JetStream which allows you to specify jetstream options
const js = jetstream(nc, { timeout: 3000 });
kvm = new Kvm(js);
// To list KVs:
await kvm.list();
// To create a KV and open it:
await kvm.create("mykv");
// To access a KV but fail if it doesn't exist:
await kvm.open("mykv");
KvWatchOption.initializedFn has been removed
Previous versions of Kv.watch() allowed the client to specify a function that
was called when the watch was done providing history values. In this version,
you can find out if a watch is yielding an update by examining the isUpdate
property. Note that an empty Kv will not yield any watch information. You can
test for this initial condition, by getting the status of the KV, and inspecting
the values property, which will state the number of entries in the Kv. Also
note that watches with the option to do updates only, cannot notify until
there's an update.
Removal of deprecations
Removed deprecated KV apis (KvRemove - remove(k)=>Promise<void>,
close()=>Promise<void>) and options (maxBucketSize,
placementCluster,bucket_location)
Removed the deprecated option backingStore from KvOptions and KvStatus.
Use KvOptions.storage and KvStatus.storage.
Changes to ObjectStore
Caution
Clients prior to 3.x used to shim the global
cryptoautomatically.cryptois available on node 20 and better. Please upgrade your node runtime or shimcrypto:if (typeof globalThis.crypto === "undefined") { const c = require("crypto"); global.crypto = c.webcrypto; }
Important
Clients that use @nats-io/obj prior to 3.0.0-34, potentially generated sha-256 digests that were incorrect due to a bug on a 3rd party library bundled in the client. The library has been replaced with npm:js-sha256. Errors in the digests usually affected 500 MB or larger objects.
If you are upgrading from a previous pre-release or from the previous generation clients (these were also updated) you may want to re-put your objects or use the tool fix-os-hashes to be compatible with 3.0.0-34 and beyond (and other NATS tools). To run the tool install deno and:
deno run -A https://github.com/nats-io/nats.deno/blob/main/bin/fix-os-hashes.ts -h
To use ObjectStore, you must install and import @nats-io/obj.
Watch
Object.watch() now returns an ObjectWatchInfo which is an ObjectInfo but
adding the property isUpdate this property is now true when the watch is
notifying of a new entry. Note that previously the iterator would yield
ObjectInfo | null, the null signal has been removed. This means that when
doing a watch on an empty ObjectStore you won't get an update notification until
an actual value arrives.
Removed deprecations
Removed deprecated ObjectStoreInfo - use ObjectStoreStatus
Changes to Services Framework
To use services, you must install and import @nats-io/services, and create an
instance of Svc, which allows you to add() a service and create a
ServiceClient client(nc):
const svc = new Svcm(nc);
const service = await svc.add({
name: "max",
version: "0.0.1",
description: "returns max number in a request",
statsHandler,
});
// other manipulation as per service api...
servicesproperty has been removed. Install and import theServiceslibrary, and callSvcm(nc: NatsConnection)