Skip to content

Architecture Overview

Last Updated: 2025-11-23

This document describes the high-level architecture of ocmonica, including the dual API design, technology stack, and request flow patterns.


Table of Contents


Dual API Architecture

Ocmonica implements a dual API architecture where both REST (Echo) and gRPC (ConnectRPC) APIs coexist as first-class citizens on the same HTTP server. This provides flexibility for different client types:

  • REST API (Echo v4): Traditional HTTP/JSON endpoints for web browsers, curl, and standard HTTP clients
  • gRPC API (ConnectRPC): Type-safe, high-performance RPC endpoints for modern web apps and native clients

Both APIs: - Share the same service layer (business logic) - Run on the same port (8080) using h2c (HTTP/2 Cleartext) - Enforce the same authentication and authorization rules - Are fully production-ready and tested

Design Philosophy

The dual API approach provides a best-of-both-worlds solution:

  • REST API: Universal compatibility, authentication management, health checks
  • gRPC API: Type safety, performance, streaming capabilities for core operations

This architecture maximizes flexibility without significant maintenance overhead. The shared service layer ensures no code duplication, and both APIs are production-ready.


Technology Stack

Backend Core

Go 1.25.2 - Modern Go features with generics support - Follows Go idioms and best practices

Echo v4.13.4 (REST Framework) - Middleware stack: Logger → Recover → CORS → Security Headers → JWT → RBAC - Group-based routing for /api/v1/* - Custom error handler for consistent responses - Documentation: https://echo.labstack.com/

ConnectRPC v1.19.1 (gRPC Framework) - Interceptors for auth and RBAC (similar to middleware) - Supports Connect, gRPC, and gRPC-Web protocols - Type-safe generated code from protobuf - Documentation: https://connectrpc.com/

SQLite (modernc.org/sqlite v1.39.0) - Pure Go implementation (no CGO) - In-memory databases for tests - Migration system - Connection pooling configured

Dependency Versions

Backend (Go) - From go.mod:

require (
    connectrpc.com/connect v1.19.1                    // ConnectRPC core
    github.com/labstack/echo/v4 v4.13.4               // Echo web framework
    github.com/labstack/echo-contrib v0.17.4          // Echo middleware
    github.com/labstack/echo-jwt/v4 v4.3.1            // JWT middleware for Echo
    google.golang.org/protobuf v1.36.10               // Protocol Buffers
    golang.org/x/net v0.46.0                          // HTTP/2 support (h2c)
)

Frontend (TypeScript/React) - From web/package.json:

{
  "dependencies": {
    "@bufbuild/protobuf": "^2.9.0",                   // Protobuf runtime
    "@connectrpc/connect": "^2.1.0",                  // ConnectRPC client core
    "@connectrpc/connect-query": "^2.2.0",            // TanStack Query integration
    "@connectrpc/connect-web": "^2.1.0",              // Web transport layer
    "@tanstack/react-query": "^5.90.2",               // Server state management
    "next": "15.5.4",                                 // React framework
    "react": "19.1.0",                                // UI library
    "axios": "1.12.2"                                 // REST API client (fallback)
  }
}

For complete technology stack details, see CLAUDE.md (Technology Stack section) in the project root.


System Architecture

High-Level Overview

The following diagram shows the complete system architecture with all major components:

System Architecture

Complete system architecture showing client layer, API gateway, middleware/interceptors, handlers, services, repositories, and observability stack.

Architecture Highlights:

  • Dual API: Both REST and gRPC on same port (8080) using h2c
  • Layered Design: Clear separation between handlers, services, and repositories
  • Shared Services: Both APIs use the same business logic layer
  • Comprehensive Observability: OpenTelemetry tracing + Prometheus metrics
  • Multi-Tenancy: Organization isolation enforced at repository layer

Request Flow

Both APIs follow a consistent request flow pattern through the application layers.

REST Request Flow

REST Request Flow

Sequence diagram showing the complete REST API request flow from client through middleware stack, handlers, services, repositories to database and back.

gRPC Request Flow

gRPC Request Flow

Sequence diagram showing the complete gRPC API request flow from client through interceptor chain, handlers, services, repositories to database and back.

Layered Architecture

The following diagram illustrates the strict layered architecture pattern:

Layered Architecture

Layered architecture showing separation between presentation layer (handlers), business logic layer (services), data access layer (repositories), and data storage.

Key Principles:

  1. Separation of Concerns: Each layer has a single responsibility
  2. Dependency Injection: Services and repositories injected into handlers
  3. Context Propagation: context.Context flows through all layers for tracing
  4. Error Handling: Errors wrapped with context at each layer
  5. No Bypassing: Always go through the full stack (no shortcuts)

For detailed patterns, see CLAUDE.md (Architecture section) in the project root.


Integration Pattern

Both APIs are integrated on a single HTTP server using h2c (HTTP/2 Cleartext):

// cmd/server/main.go (lines 343-351)
server := &http.Server{
    Addr:    fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port),
    Handler: h2c.NewHandler(e, &http2.Server{}),  // h2c enables gRPC + REST on same port
}

Key Architecture Points: 1. Single Port: Both APIs accessible on port 8080 2. Path Separation: - REST: /api/v1/* - gRPC: /ocmonica.v1.*/* 3. Shared Service Layer: Both handlers call the same business logic services 4. Unified Auth: Both use JWT tokens with same validation


Protocol Support

ConnectRPC Protocol Support

ConnectRPC supports three protocols on the same endpoint:

  1. Connect Protocol (recommended)
  2. JSON or binary encoding
  3. Browser-friendly (uses standard HTTP/POST)
  4. Best for web applications

  5. gRPC Protocol

  6. Binary Protocol Buffers encoding
  7. Requires HTTP/2
  8. Best for server-to-server

  9. gRPC-Web Protocol

  10. Compatible with gRPC proxies (e.g., Envoy)
  11. Works with existing gRPC infrastructure

Client Selection:

// Frontend: Use Connect protocol with JSON (easy debugging)
const transport = createConnectTransport({
  baseUrl: 'http://localhost:8080',
  useBinaryFormat: false,  // JSON format
});

// Or use binary format for better performance
const transport = createConnectTransport({
  baseUrl: 'http://localhost:8080',
  useBinaryFormat: true,  // Protocol Buffers binary
});

Echo REST Protocol Support

  • HTTP/1.1: Full support
  • HTTP/2: Supported via h2c
  • WebSocket: Supported via Echo WebSocket middleware
  • Content Types: JSON (primary), XML, form data, multipart

Multi-Tenancy Architecture

Ocmonica implements complete data isolation between organizations through a comprehensive multi-tenancy model.

Data Model

Data Model

Entity-relationship diagram showing the complete database schema including organizations, users, files, roles, permissions, and groups with their relationships and key attributes.

Organization Isolation

The following diagram shows how data isolation is enforced:

Organization Isolation

Flow diagram illustrating how organization-based data isolation is enforced through multiple layers: request context extraction, middleware validation, service filtering, and repository-level WHERE clauses.

Isolation Guarantees:

  1. Context-Based: Organization ID extracted from JWT token
  2. Middleware Enforcement: Early validation of organization access
  3. Service Layer: Business logic respects organization boundaries
  4. Repository Layer: All queries include WHERE organization_id = ?
  5. Database Level: Foreign key constraints ensure referential integrity

Security Rules:

  • Users can only access resources in their organization
  • Cross-organization access is forbidden (returns 404, not 403)
  • All database queries MUST filter by organization_id
  • Missing organization filter is a critical security vulnerability

For implementation details, see Authentication & Authorization Guide.


See Also