← All articles
Architecture·3 min read

Inside Djengo: one gateway, ten services, two languages

How Djengo is wired: an nginx edge, a NestJS REST gateway, and domain services in NestJS and .NET 8 that talk over gRPC and RabbitMQ, plus what that split costs.

djengoarchitecturemicroservicesgrpcbackend
On this page

The shape of the system#

Every browser and mobile request enters through nginx, which terminates HTTP and rate limits at 10 requests per second per IP. Behind it sits a single REST gateway. The gateway authenticates, applies tenant scope, and fans out to domain services over gRPC. Side effects that do not need an answer right away travel over RabbitMQ.

text
Browsers / mobile
       │ HTTPS
       ▼
   nginx  (TLS, 10 req/s per IP)
       │
       ▼
 gateway-service  (NestJS REST, /api/v0.0.1)
   auth guards · tenant scope · JWT → gRPC metadata
       │ gRPC
       ├─ profile        identity, sessions, staff
       ├─ organization   orgs, companies, branches, roles
       ├─ events         attendance, leave, approvals   (.NET 8)
       ├─ financials     payroll, budgets, deductions   (.NET 8)
       ├─ operations     reservations, orders, kitchen  (.NET 8)
       ├─ facility       physical layout per branch
       └─ files · communications · address · admin

 RabbitMQ: registration → org setup, emails, approval and payslip notices
Simplified from the Djengo project map.

Why these boundaries#

ServiceStackWhy it stands alone
profileNestJS + PrismaIdentity, sessions, and lockouts change on a security cadence, not a feature cadence
organizationNestJS + PrismaThe tenant tree everyone else reads from; a small, stable contract
financialsC# .NET 8 + EF CorePayroll and budgets need strict state machines and their own audit trail
eventsC# .NET 8 + EF CoreHR workflows, approvals, and background jobs like contract-expiry alerts
operationsC# .NET 8 + EF CoreOrders and kitchen tickets spike at service time without touching payroll

Each service owns its own PostgreSQL database. There are no cross-service joins. If financials needs a company's payroll policy, it asks organization over gRPC. That rule is annoying on day one and invaluable the first time you need to change a schema without coordinating five teams' worth of code.

Why two languages#

The gateway, identity, and organization services are NestJS, so their types sit close to the Next.js and React Native clients. The money and workflow services are .NET 8, where EF Core migrations, hosted background services, and a strict type system suit long-lived financial records. The language is chosen per domain, and gRPC makes the choice invisible to callers.

The contracts are the real product#

The busiest backend repository in Djengo is not a service. It is djengo-proto-contracts, with 614 commits, roughly five times the next backend repo. Every change to a boundary starts as a change to a .proto file. That is where the design arguments happen, and that is where they should happen.

  • Auth travels on every hop: the gateway injects the JWT into gRPC metadata, NestJS services check it with a gRPC guard, C# services with a server interceptor.
  • Tenant scope travels with it: organization, company, and branch ids ride in metadata, not in request bodies.
  • Async work is for side effects only: welcome emails, approval notices, payslip delivery. Anything the user waits on is a gRPC call.

What it costs#

  1. 1Local development needs Docker Compose to bring up Postgres, Redis, RabbitMQ, and a dozen processes.
  2. 2Debugging a request means following it across hops, so logs need correlation from the start.
  3. 3Proto changes need discipline: additive first, remove later, never rename in place.
  4. 4More deployables means more Dockerfiles, more health checks, and more environments to keep honest.

I pay those costs knowingly. The alternative, payroll, kitchen tickets, and login lockouts sharing one deploy and one database, would be cheaper this month and more dangerous every month after.

Key takeaways

What to remember

  • One REST gateway, domain services behind gRPC.
  • Each service owns its database; no cross-service joins.
  • The proto contracts are where design happens.
Isaac Tubonibo

Written by

Isaac Tubonibo

Founder of Djengo · Software Engineer

Founder of Djengo, operations software for hotels, hospitals, estates, and restaurants. I build it end to end: architecture, delivery, and the human side of shipping under pressure.

More from the archive

Related articles