DEV Community

Cover image for LioranDB TypeScript Series #3: Connection Strings, Transports and Client Lifecycle
Swaraj Puppalwar
Swaraj Puppalwar

Posted on

LioranDB TypeScript Series #3: Connection Strings, Transports and Client Lifecycle

LioranDB TypeScript Series #3: Connection Strings, Transports and Client Lifecycle

LioranDB TypeScript Series: Build with a developer-first document database powered by Rust and designed for TypeScript.

We connected to LioranDB in Part 2 with one line:

const client = await LioranDBClient.connect(process.env.URI!);
Enter fullscreen mode Exit fullscreen mode

There's quite a bit happening underneath it.

Let's unpack it.

Connection URI

A typical local URI looks like:

liorandb://admin:password@127.0.0.1:27018/default
Enter fullscreen mode Exit fullscreen mode

Conceptually:

liorandb:// USER : PASSWORD @ HOST : PORT / DATABASE
Enter fullscreen mode Exit fullscreen mode

LioranDB understands multiple schemes:

liorandb://
liorandb+http://
liorandb+https://
http://
https://
grpc://
Enter fullscreen mode Exit fullscreen mode

For example:

liorandb://admin:password@127.0.0.1:27018/default
Enter fullscreen mode Exit fullscreen mode

or:

liorandb+https://admin:password@db.example.com/default
Enter fullscreen mode Exit fullscreen mode

Reserved characters matter

Suppose your password is:

hello@database#123
Enter fullscreen mode Exit fullscreen mode

Don't place that directly inside the URI.

Encode it:

const password = encodeURIComponent("hello@database#123");

const uri =
  `liorandb://admin:${password}@127.0.0.1:27018/default`;
Enter fullscreen mode Exit fullscreen mode

This avoids the URI parser interpreting password characters as URI syntax.

Parsing connection strings

The driver exposes its parser:

import { parseConnectionString } from "@liorandb/driver";

const config = parseConnectionString(
  "liorandb://admin:password@127.0.0.1:27018/default"
);

console.log(config);
Enter fullscreen mode Exit fullscreen mode

This is useful for tooling, debugging and infrastructure layers that need to inspect connection configuration.

Client options

You can also configure the client explicitly.

const client = await LioranDBClient.connect(uri, {
  transport: "auto",
  autoRefreshTokens: true,
  logoutOnClose: true,
  requestTimeoutMS: 5000,
  slowRequestThresholdMS: 200,

  onWarning(warning) {
    console.warn(
      `[${warning.code}] ${warning.message}`
    );
  },
});
Enter fullscreen mode Exit fullscreen mode

Important options include:

  • transport
  • timeoutMS
  • connectTimeoutMS
  • requestTimeoutMS
  • grpcChannels
  • maxRetries
  • retryDelayMS
  • autoRefreshTokens
  • logoutOnClose
  • appName
  • slowRequestThresholdMS
  • onWarning

For most applications, transport: "auto" is the sensible starting point.

Diagnostics

You can attach diagnostic headers:

client.setDiagnosticHeaders({
  "x-trace-id": "request-001",
});
Enter fullscreen mode Exit fullscreen mode

And observe responses:

client.setResponseObserver((event) => {
  console.log({
    transport: event.transport,
    operation: event.operation,
    durationMS: event.durationMS,
    requestId: event.requestId,
  });
});
Enter fullscreen mode Exit fullscreen mode

This becomes especially useful when debugging latency or transport behavior.

Health and discovery

The client also provides helpers for inspecting the server:

await client.live();
await client.ready();
await client.serverInfo();
await client.listDatabases();
Enter fullscreen mode Exit fullscreen mode

Client lifecycle

A good application lifecycle looks like this:

const client = await LioranDBClient.connect(uri);

try {
  const db = client.db("default");

  // application work
} finally {
  await client.close();
}
Enter fullscreen mode Exit fullscreen mode

Closing the client cleans up its resources, transports and cursors.

Attempting to use a closed client results in ClientClosedError.

One client, many collections

Don't create a new database connection for every query.

Create the client at the appropriate application lifecycle boundary and reuse it.

Application
    ↓
LioranDBClient
    ├── users
    ├── products
    ├── sessions
    └── events
Enter fullscreen mode Exit fullscreen mode

That's both cleaner and considerably closer to how a database client is intended to be used.

Resources

Connection & Client Docs:
https://docs.liorandb.com/docs/driver/connection-and-client

Documentation: https://docs.liorandb.com
Website: https://liorandb.com
Creator: https://github.com/UltronTheAI


Previous: Part 2 → Docker & First Query
Next: Part 4 → Databases, Collections & Typed CRUD



Enter fullscreen mode Exit fullscreen mode

Top comments (0)