Features Apograph CMS on GitHub

Database plugin

The connection, the transaction boundary, and the event outbox underneath everything else.

Documents 0.5.2 Updated Edit this page Report a problem

On this page

The first plugin in the list, and the only one that opens a resource in onPluginInit. It contributes no routes and no UI. What it gives the rest of the system is three things: a connection pool, a transaction boundary, and a transactional outbox.

Install

npm install @apograph/database

Register

import { DatabasePlugin } from '@apograph/database';

DatabasePlugin({ connectionString: config.database.url });

It goes first. Every other plugin’s migrations and repositories resolve against the connection it opens.

Environment

VariableDefaultWhat it does
DATABASE_URLnone — requiredPostgres connection string. The app refuses to load without it

There is no usable default. Left unset, the value reaches pg as “use the libpq defaults” and the first query fails with whatever the local environment happens to produce — a message that names everything except the variable nobody set. apograph.config.ts fails at load instead.

What it gives other plugins

The pool. InjectDatabase hands a plugin the Drizzle instance. Nothing else opens a connection.

import { InjectDatabase, type Database } from '@apograph/database';

class EntryRepository {
    constructor(@InjectDatabase() private readonly db: Database) {}
}

The unit of work. UnitOfWork.run is the transaction boundary a state change happens inside. Every write in a use case — the row, its revision, and its domain event — commits together or not at all.

The outbox. Domain events are written to outbox_events in the same transaction as the row that caused them, then dispatched after the commit. That is what makes the activity log a subscriber rather than a second write nobody can roll back.

The pool drains on shutdown

Shutdown waits for the in-flight outbox batch and then closes the pool, so a deploy does not sever a dispatch mid-flight.

Migrations

Every plugin ships its own migrations and owns its own __drizzle_migrations_* table. apograph migrate walks the plugin list in order and applies each one — see the database and migrations for the deployment sequence, and the CLI for the commands.