PrimeBrickPrimeBrick
  • Docs
  • Contact
  • MIT License
  • Documentation
  • MCP Server
  • API Catalog
  • Services
  • Libraries
PrimeBrickPrimeBrick

© 2026 PrimeBrick. MIT License. v3.8.0

github
Backend
Frontend
Microservices
    Microservices OverviewArchitectureConventions
    Services
powered by Zudoku
Microservices

Architecture

Primebrick v3 microservices follow a gateway-proxied architecture with NATS for async messaging and per-service database isolation.

Backend proxy

The Backend (BE) acts as the API gateway for all microservices. The Frontend (FE) never calls microservices directly.

  • HTTP proxy: The BE proxies requests via /ws/:serviceCode/*. A request to GET /ws/emailsender/api/v1/entities/providers/list is forwarded to the EmailSender microservice at GET /api/v1/entities/providers/list.
  • OpenAPI aggregation: The BE fetches each microservice's GET /api/v1/openapi.json and merges the specs into a unified API catalog. This powers the Zudoku API explorer on the docs site.
  • MCP Server: The BE's MCP Server uses the aggregated OpenAPI specs to generate generic CRUD tools. The standardized entity CRUD path pattern (/api/v1/entities/:entity/...) allows the MCP Server to dispatch tools without per-entity path configuration.

NATS message bus

Microservices connect to NATS via the SDK's NatsClient. NATS is used for:

  1. Service registration — microservices publish register/heartbeat/ unregister events; the BE subscribes and persists to public.service_registry
  2. Async request/reply — the BE publishes requests (e.g. emailsender.send) and microservices reply on a per-request response subject (e.g. emailsender.response.{requestId})

NATS authentication uses the SDK's GATEWAY-RESOLVED mode — the BE forwards JWT/auth headers via NATS message headers, and the microservice verifies them with verifyNatsMessage().

SDK lifecycle

Every microservice uses @primebrick/sdk for its lifecycle:

  1. Environment validation — requireEnv() validates required env vars at startup
  2. Config loading — ConfigLoader reads the config table for service-specific settings (NATS URL, HTTP port, service code)
  3. Auth config — initAuthConfig() + loadAuthConfig() set up GATEWAY-RESOLVED auth mode
  4. NATS connection — NatsClient.getConnection(url)
  5. Service registration — ServiceRegistrar.register() publishes the register event, then startHeartbeat() begins periodic health checks
  6. HTTP server — createHttpServer() starts the HTTP listener with health check and route handler
  7. Graceful shutdown — GracefulShutdown coordinator runs cleanup on SIGTERM/SIGINT: stop heartbeat → unregister → close NATS → close DB → close HTTP

Database isolation

Each microservice has its own PostgreSQL schema (e.g. emailsender). Microservices never read or write to another microservice's schema. The only shared table is public.service_registry, which lives in the public schema and is used for service registration.

  • DAL: @primebrick/dal-pg with entity decorators (@Entity, @Column, @Key, @Unique, @AuditableField, @DeletableField)
  • Migrations: each microservice has its own db-meta/patches/ directory, applied via @primebrick/sdk's applyPatches() runner
  • Schema override: the @Entity decorator accepts an optional second argument for the schema name (e.g. @Entity("service_registry", "public"))

Next steps

  • Conventions — API path conventions, data model rules
  • EmailSender — Email sending microservice
Last modified on July 26, 2026
Microservices OverviewConventions
On this page
  • Backend proxy
  • NATS message bus
  • SDK lifecycle
  • Database isolation
  • Next steps