A NodeJS client for Event Store
EventStoreDB is the event-native database, where business events are immutably stored and streamed. Designed for event-sourced, event-driven, and microservices architectures.
This is the repository for the NodeJS client for EventStoreDB 20+ and uses gRPC as the communication protocol.
# Yarn
$ yarn add @eventstore/db-client
# NPM
$ npm install --save @eventstore/db-client
This client is compatible with version 20.6.1
upwards.
Server setup instructions can be found under the installation section of the Event Store Docs. Follow the Docker setup for the simplest configuration.
Full documentation can be found in Event Store GRPC Client Docs.
The following snippet showcases a simple example where we form a connection, then append and read events from the server.
const {
EventStoreDBClient,
jsonEvent,
FORWARDS,
START,
} = require('@eventstore/db-client');
const client = new EventStoreDBClient(
{
endpoint: 'localhost:2113',
},
{ insecure: true }
);
(async () => {
try {
const streamName = 'booking-transactions';
// define an event
const event = jsonEvent({
type: 'booking-initiated',
data: {
bookingId: 'booking-456',
userId: 'user-789',
event: 'Concert of The Rolling Stones',
timestamp: new Date().toISOString(),
},
metadata: {
createdByUserId: 'user-789',
sourceIp: '192.168.1.100',
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
}
});
// append the event
await client.appendToStream(streamName, [event]);
// read the event
const events = client.readStream(streamName, {
fromRevision: START,
direction: FORWARDS,
maxCount: 10,
});
for await (const { event } of events) {
console.log('Appended event: ', event);
}
} catch (error) {
console.error('An error occured: ', error);
} finally {
await client.dispose();
}
})();
import {
EventStoreDBClient,
jsonEvent,
FORWARDS,
START,
type JSONEventType,
} from "@eventstore/db-client";
// Create a client to connect to EventStoreDB
const client = EventStoreDBClient.connectionString`esdb://localhost:2113`;
// Define the events that can occur during a booking
type SeatReservedEvent = JSONEventType<
"seat-reserved",
{
reservationId: string;
movieId: string;
userId: string;
seatId: string;
}
>;
type SeatChangedEvent = JSONEventType<
"seat-changed",
{
reservationId: string;
newSeatId: string;
}
>;
type ReservationEvents = SeatReservedEvent | SeatChangedEvent;
// Write events to a stream that describe the history of our booking
const streamName = "booking-abc123";
const event = jsonEvent<SeatReservedEvent>({
type: "seat-reserved",
data: {
reservationId: "abc123",
movieId: "tt0368226",
userId: "nm0802995",
seatId: "4b",
},
});
const appendResult = await client.appendToStream<ReservationEvents>(
streamName,
event
);
// By reading the events in the stream, we can construct the current state of the booking
interface Reservation {
reservationId: string;
movieId: string;
userId: string;
seatId: string;
}
const events = client.readStream<ReservationEvents>(streamName, {
fromRevision: START,
direction: FORWARDS,
maxCount: 10,
});
const reservation: Partial<Reservation> = {};
for await (const { event } of events) {
switch (event?.type) {
case "seat-reserved": {
reservation.reservationId = event.data.reservationId;
reservation.movieId = event.data.movieId;
reservation.seatId = event.data.seatId;
reservation.userId = event.data.userId;
break;
}
case "seat-changed": {
reservation.seatId = event.data.newSeatId;
break;
}
}
}
// Do something with our reservation
console.log(reservation);
This project uses Yarn as a build tool. The following shell command lines should get you started:
$ yarn
$ yarn build
Tests are written using Jest and require Docker and Docker Compose to be installed. Then run test with:
$ yarn test
Tests can be filtered by prepending the test file or folder to the command
$ yarn test connection // all connection tests
$ yarn test ReadAll // only the ReadAll tests
To get debug information when running tests use the test:debug
command.
$ yarn test:debug // debug all tests
$ yarn test:debug ReadAll // only the ReadAll tests
Specific docker images can be specified via the enviroment variable EVENTSTORE_IMAGE
.
$ yarn cross-env EVENTSTORE_IMAGE=77d63f3f0ab3 jest
See Jest documentation for more options.
This project uses the debug module internally to log information about connections, options and GRPC requests.
To see all the internal logs, set the DEBUG environment variable to esdb:*
when launching your app.
Logs can be further filtered with glob patterns, for example, only connection logs: esdb:connection
, everything but grpc logs: esdb:*,-*:grpc
.
You can set a few environment variables that will further change the behavior of the debug logging:
Name | Purpose |
---|---|
DEBUG |
Enables/disables specific debugging namespaces. |
DEBUG_COLORS |
Whether or not to use colors in the debug output. |
DEBUG_DEPTH |
Object inspection depth. |
DEBUG_FD |
File descriptor to write debug output to. |
DEBUG_SHOW_HIDDEN |
Shows hidden properties on inspected objects. |
Note: The environment variables beginning with DEBUG_
end up being
converted into an Options object that gets used with %o
/%O
formatters.
See the Node.js documentation for util.inspect()
for the complete list.
Information on support can be found on our website: Event Store Support
Development is done on the master
branch. We attempt to do our best to ensure that the history remains clean and to do so, we generally ask contributors to squash their commits into a set or single logical commit.