PrimebrickPrimebrick
  • Primebrick.dev
  • GitHub
  • Documentation
  • Backend
  • Frontend
  • Microservices
  • DAL
  • SDK
  • API Catalog
Resources
  • Landing Page
  • API Catalog
  • GitHub
PrimebrickPrimebrick

© 2026 Primebrick. MIT License.

github
Architecture: Ports & AdaptersBuild, Tooling & CI/CDCI/CD & NPM PublishingConfiguration ManagementCore ModulesDatabase MigrationsEnvironment ValidationGetting StartedGlossaryHTTP Server & Health ChecksLifecycle & Graceful ShutdownModule Test PatternsNATS Messaging ClientOverviewService Registration & HeartbeatTest Infrastructure & ConfigurationTestingTypeScript Build ConfigurationREADME
powered by Zudoku
SDK

Architecture: Ports & Adapters

Architecture: Ports & Adapters

Relevant source files

The following files were used as context for generating this wiki page:

  • README.md
  • src/ports/config-repository-port.ts
  • src/ports/database-port.ts
  • src/ports/health-check-port.ts
  • src/ports/service-registry-port.ts

The @primebrick/sdk is built on the Hexagonal Architecture (also known as Ports & Adapters) pattern. The primary goal of this design is to make the SDK entirely database-agnostic and decoupled from specific Data Access Layer (DAL) implementations README.md:3-7.

By defining abstract "Ports" (interfaces), the SDK core logic remains pure and testable, while the consuming microservice is responsible for providing "Adapters" (concrete implementations) that bridge the SDK to specific infrastructure like PostgreSQL, MSSQL, or MariaDB src/ports/database-port.ts:4-6.

Dependency Inversion Principle

The SDK applies the Dependency Inversion Principle (DIP) to ensure that high-level modules (like the Migration Runner or Config Loader) do not depend on low-level modules (like a specific database driver). Instead, both depend on abstractions src/ports/config-repository-port.ts:4-7.

Data Flow: SDK to Infrastructure

The following diagram illustrates how the SDK interacts with external systems through ports.

Entity Mapping: SDK Ports to Infrastructure

Code
graph LR subgraph "SDK Core (Natural Language Space)" CL["ConfigLoader"] MR["Migration Runner"] SR["ServiceRegistrar"] HC["HealthCheck"] end subgraph "Port Interfaces (Code Entity Space)" CRP["ConfigRepositoryPort"] DP["DatabasePort"] SRP["ServiceRegistryPort"] HCP["HealthCheckPort"] end subgraph "Consumer Adapters (Implementation Space)" PG_CRP["PostgresConfigAdapter"] PG_DP["PostgresQueryAdapter"] PG_SRP["PostgresRegistryAdapter"] PG_HCP["PostgresPingAdapter"] end CL --> CRP MR --> DP SR --> SRP HC --> HCP CRP -.-> PG_CRP DP -.-> PG_DP SRP -.-> PG_SRP HCP -.-> PG_HCP

Sources: src/ports/config-repository-port.ts:8-14, src/ports/database-port.ts:11-17, src/ports/health-check-port.ts:8-11, src/ports/service-registry-port.ts:10-19


The Four Port Interfaces

The SDK defines four primary ports that must be implemented by the consuming application to enable full functionality.

1. ConfigRepositoryPort

Used by the ConfigLoader to fetch application settings from a persistent store src/ports/config-repository-port.ts:4-7.

MethodDescription
findAll()Returns all configuration rows as an array of { key, value } pairs. Value is null if the key exists without a value src/ports/config-repository-port.ts:13-13.

Sources: src/ports/config-repository-port.ts:8-14

2. DatabasePort

A low-level interface for executing parameterized SQL. This is the backbone of the SDK's migration runner (applyPatches) src/ports/database-port.ts:4-6.

MethodDescription
query<T>(text, params?)Executes a SQL statement. Returns an object containing a rows array. Used for transaction control (BEGIN, COMMIT) and patch execution src/ports/database-port.ts:13-16.

Sources: src/ports/database-port.ts:11-17

3. ServiceRegistryPort

Used by the ServiceRegistrar to manage the lifecycle and heartbeat of the microservice within a centralized registry table src/ports/service-registry-port.ts:4-9.

MethodDescription
findByCode(code)Retrieves a service record by its unique code src/ports/service-registry-port.ts:12-12.
insert(row)Adds a new service entry to the registry src/ports/service-registry-port.ts:15-15.
updateByCode(code, row)Updates an existing service record (e.g., updating the heartbeat timestamp) src/ports/service-registry-port.ts:18-18.

Sources: src/ports/service-registry-port.ts:10-19

4. HealthCheckPort

A specialized port for connectivity pings. It allows the SDK's HealthCheck utility to verify database availability without knowing the specific SQL dialect src/ports/health-check-port.ts:4-7.

MethodDescription
ping()Returns a boolean indicating if the database is reachable (e.g., by running SELECT 1) src/ports/health-check-port.ts:9-10.

Sources: src/ports/health-check-port.ts:8-11


Implementing Adapters

Consumers write adapter implementations by wrapping their chosen database driver or Data Access Layer.

Implementation Pattern

The consumer provides these implementations at startup, injecting them into the SDK's functional modules.

Code Entity Relationship: Adapter Implementation

Code
classDiagram class DatabasePort { <<interface>> +query(text, params) } class PostgresAdapter { -pool: pg.Pool +query(text, params) } class MigrationRunner { +applyPatches(dbPort: DatabasePort) } DatabasePort <|.. PostgresAdapter : Implements MigrationRunner --> DatabasePort : Depends on

Sources: src/ports/database-port.ts:1-17, README.md:7-7

Key Requirements for Adapters:

  1. Error Handling: Adapters should catch driver-specific errors and allow them to bubble up or wrap them in a way the SDK can log.
  2. Type Safety: The DatabasePort uses generics (<T = unknown>) to allow consumers to maintain type safety when fetching rows src/ports/database-port.ts:16-16.
  3. Statelessness: Ports are generally designed to be stateless, acting as a pass-through to the underlying connection pool or client src/ports/database-port.ts:8-10.

Sources: src/ports/database-port.ts:1-17, src/ports/config-repository-port.ts:1-14, src/ports/service-registry-port.ts:1-19, src/ports/health-check-port.ts:1-11


Last modified on July 13, 2026
Build, Tooling & CI/CD
On this page
  • Dependency Inversion Principle
    • Data Flow: SDK to Infrastructure
  • The Four Port Interfaces
    • 1. ConfigRepositoryPort
    • 2. DatabasePort
    • 3. ServiceRegistryPort
    • 4. HealthCheckPort
  • Implementing Adapters
    • Implementation Pattern
    • Key Requirements for Adapters: