Skip to content

Gustavo-Murdiga88/grpc

Repository files navigation

gRPC Microservice with Clean Architecture

A production-ready TypeScript-based microservice implementing Clean Architecture principles with gRPC and HTTP interfaces, Redis caching, PostgreSQL database, and comprehensive observability stack.

πŸ—οΈ Architecture Overview

This project follows Clean Architecture (Hexagonal Architecture) with clear separation of concerns:

src/
β”œβ”€β”€ app/                        # Application layer (interface adapters)
β”‚   β”œβ”€β”€ grpc/                  # gRPC server implementation
β”‚   β”‚   β”œβ”€β”€ server.ts          # gRPC server setup
β”‚   β”‚   β”œβ”€β”€ handlers/          # gRPC method handlers
β”‚   β”‚   β”œβ”€β”€ ioc/              # Inversion of Control containers
β”‚   β”‚   └── mappers/          # Data mapping utilities
β”‚   └── http/                  # HTTP server implementation
β”‚       β”œβ”€β”€ server.ts          # Fastify HTTP server setup
β”‚       β”œβ”€β”€ controllers/       # HTTP route controllers
β”‚       β”œβ”€β”€ mappers/          # HTTP data mappers
β”‚       └── transporters/     # HTTP transport layer
β”œβ”€β”€ core/                      # Core utilities and shared logic
β”‚   β”œβ”€β”€ either.ts/.spec.ts     # Functional error handling (Either monad)
β”‚   β”œβ”€β”€ entities/              # Base entity classes and value objects
β”‚   β”œβ”€β”€ errors/                # Custom error classes
β”‚   └── types/                 # Shared type definitions
β”œβ”€β”€ domain/                    # Business logic layer (entities and use cases)
β”‚   β”œβ”€β”€ cache/                 # Cache domain interfaces
β”‚   β”‚   └── repositories/      # Cache repository contracts
β”‚   β”œβ”€β”€ customer/              # Customer domain
β”‚   β”‚   β”œβ”€β”€ customers.ts       # Customer entity
β”‚   β”‚   β”œβ”€β”€ adapters/          # Domain adapters
β”‚   β”‚   β”œβ”€β”€ repositories/      # Customer repository interfaces
β”‚   β”‚   └── use-case/         # Customer business use cases
β”‚   └── store/                 # Store domain
β”‚       β”œβ”€β”€ store.ts           # Store entity
β”‚       β”œβ”€β”€ adapters/          # Store adapters
β”‚       β”œβ”€β”€ repositories/      # Store repository interfaces
β”‚       └── use-case/         # Store business use cases
└── infra/                     # Infrastructure layer (external concerns)
    β”œβ”€β”€ client.ts              # External client configurations
    β”œβ”€β”€ server-grpc.ts         # gRPC server entry point
    β”œβ”€β”€ server-http.ts         # HTTP server entry point
    β”œβ”€β”€ cache/                 # Cache implementations
    β”‚   └── redis/            # Redis client and repositories
    └── db/                    # Database implementations
        └── prisma/           # Prisma ORM integration

🎯 Design Patterns

Clean Architecture Layers

  • Domain Layer: Contains business entities, use cases, and repository interfaces
  • Infrastructure Layer: Contains implementations of repositories, gRPC services, HTTP endpoints, and external dependencies
  • Core Layer: Contains shared utilities and error handling

Patterns Used

  • Repository Pattern: Abstracts data access logic for both database and cache
  • Use Case Pattern: Encapsulates business logic
  • Factory Pattern: Creates and wires dependencies
  • Either Pattern: Functional error handling without exceptions
  • Cache-Aside Pattern: Performance optimization with Redis caching

πŸš€ Key Features

  • Dual Interface: Both gRPC and HTTP REST endpoints
  • gRPC Communication: High-performance RPC with Protocol Buffers
  • TypeScript: Full type safety across the application
  • Clean Architecture: Domain-driven design with clear separation of concerns
  • Functional Error Handling: Using Either monad for explicit error handling
  • Redis Caching: Performance optimization with intelligent caching strategies
  • PostgreSQL + Prisma: Robust database with type-safe ORM
  • Observability Stack: Prometheus metrics, Grafana dashboards, and Loki logging
  • Environment Validation: Type-safe configuration with Zod
  • Testing: Comprehensive test suite with Vitest
  • Code Quality: Automated linting and formatting with Biome

πŸ› οΈ Technology Stack

Core Technologies

  • Language: TypeScript (ES2022, ESM modules)
  • gRPC: @grpc/grpc-js with Protocol Buffer code generation
  • HTTP Server: Fastify with Pino logging
  • Database: PostgreSQL with Prisma ORM and pg adapter
  • Cache: Redis with connection pooling
  • Package Manager: pnpm with workspace support

Development Tools

  • Code Quality: Biome (ESLint + Prettier replacement)
  • Testing: Vitest with TypeScript support
  • Build: tsx for development, TypeScript compiler for production
  • Database: Prisma migrations and introspection
  • Containerization: Docker Compose for local development

Monitoring & Observability

  • Metrics: Prometheus with prom-client
  • Visualization: Grafana dashboards
  • Logging: Pino with Loki integration
  • Monitoring: Grafana Alloy for telemetry collection

🐳 Infrastructure Services

The project includes a complete local development stack:

services:
  postgres:    # PostgreSQL database (port 5432)
  redis:       # Redis cache (port 6379, password: redis)
  prometheus:  # Metrics collection (port 9090)
  grafana:     # Monitoring dashboards (port 3001)
  loki:        # Log aggregation
  alloy:       # Telemetry collection agent

πŸ“¦ Installation

Prerequisites

  • Node.js 18+
  • pnpm 10.28.2+
  • Docker and Docker Compose

Setup

# Clone the repository
git clone <repository-url>
cd grpc

# Install dependencies
pnpm install

# Start infrastructure services
docker-compose up -d

# Generate Protocol Buffer types
pnpm run build:proto

# Run database migrations
pnpm run migrate

# Generate Prisma client
pnpm run generate

# Seed the database (optional)
pnpm run seed

πŸƒβ€β™‚οΈ Running the Application

Development Mode

# Start gRPC server (port 50051)
pnpm run start:dev:grpc

# Start HTTP server (port 3000) 
pnpm run start:dev:http

# Or run both servers simultaneously
# Terminal 1:
pnpm run start:dev:grpc

# Terminal 2: 
pnpm run start:dev:http

Available Services

  • gRPC Server: localhost:50051
  • HTTP Server: localhost:3000
  • Grafana Dashboard: http://localhost:3001
  • Prometheus Metrics: http://localhost:9090
  • PostgreSQL: localhost:5432 (user: grpc, password: grpc, database: grpc)
  • Redis: localhost:6379 (password: redis)

οΏ½ API Reference

gRPC Services

The project implements the StoresService defined in proto/stores.proto:

service StoresService {
  rpc ListStores(Void) returns (StoresResponse) {}
  rpc ListCustomers(Void) returns (CustomersListResponse) {}
  rpc CreateCustomer(CreateCustomerRequest) returns (Void) {}
  rpc CreateStore(CreateStoreRequest) returns (Void) {}
}

Available Methods:

  • ListStores: Get all stores
  • ListCustomers: Get all customers
  • CreateCustomer: Create a new customer
  • CreateStore: Create a new store

HTTP Endpoints

RESTful API endpoints mirroring gRPC functionality:

  • GET /stores - List all stores
  • GET /customers - List all customers
  • POST /customers - Create a new customer
  • POST /stores - Create a new store

πŸ“‹ Domain Use Cases

Store Management

  • ListStores: Retrieves all stores with caching
  • CreateStore: Creates new store with validation

Customer Management

  • ListCustomers: Retrieves customers with intelligent caching strategy:
    1. Cache Check: First checks Redis cache for existing customers
    2. Database Fallback: If cache miss, fetches from PostgreSQL
    3. Cache Population: Stores results in Redis with TTL
    4. Error Handling: Returns Either<Error, Customer[]> for explicit error handling
  • CreateCustomer: Creates new customer with business validation

πŸ”„ Data Flow

gRPC Flow

gRPC Client β†’ gRPC Server β†’ Container β†’ Use Case β†’ Cache/Repository β†’ Response

HTTP Flow

HTTP Client β†’ Fastify β†’ Controller β†’ Use Case β†’ Cache/Repository β†’ Response

Cache Strategy

Request β†’ Redis Check β†’ [Hit: Return Data] or [Miss: PostgreSQL β†’ Cache β†’ Return Data]

## πŸ”§ Development Commands

Build & Development

# Generate Protocol Buffer types from .proto files  
pnpm run build:proto

# Run database migrations
pnpm run migrate

# Generate Prisma client
pnpm run generate

# Start gRPC server in watch mode
pnpm run start:dev:grpc

# Start HTTP server in watch mode  
pnpm run start:dev:http

# Seed database with test data
pnpm run seed

Code Quality

# Lint and format with Biome
pnpm run lint

# Run all tests
pnpm test

# Run tests in watch mode
pnpm run test:watch

Database Operations

# Open Prisma Studio (database GUI)
npx prisma studio

# Reset database (development only)
npx prisma migrate reset

# Deploy migrations (production)
npx prisma migrate deploy

πŸ§ͺ Testing

The project uses Vitest for testing with full TypeScript support:

# Run all tests once
pnpm test

# Run tests in watch mode
pnpm run test:watch

# Run tests with coverage
pnpm run test:coverage

Test structure:

  • Unit tests: src/**/*.spec.ts
  • Integration tests: test/**/*.test.ts
  • Domain tests: test/domain/**/*.test.ts
  • Cache tests: test/cache/**/*.test.ts

πŸ“ Environment Configuration

Create a .env file in the project root:

# Database
DATABASE_URL="postgres://grpc:grpc@localhost:5432/grpc"

# Cache
REDIS_URL="redis://localhost:6379"
REDIS_PASSWORD="redis"

# Application
NODE_ENV="development"
LOG_LEVEL="info"

# gRPC
GRPC_PORT="50051"

# HTTP
HTTP_PORT="3000"

πŸš€ Production Deployment

Build Process

# Build TypeScript for production
pnpm run build

# Or use the production Dockerfile
docker build -t grpc-microservice .

Environment Setup

  1. Database: Configure PostgreSQL connection string
  2. Cache: Set up Redis instance with authentication
  3. Environment Variables: Set production environment variables
  4. Monitoring: Configure Prometheus scraping and Grafana dashboards
  5. Logging: Set up log aggregation with appropriate log levels

Deployment Checklist

  • Set NODE_ENV=production
  • Configure database migrations
  • Set up Redis with persistence
  • Configure monitoring and alerting
  • Set up log aggregation
  • Configure SSL/TLS certificates
  • Set up load balancing (if needed)
  • Configure backup strategies

πŸ“Š Monitoring & Observability

Metrics (Prometheus)

  • Application metrics via prom-client
  • Database connection pool metrics
  • Cache hit/miss ratios
  • Request latency and throughput
  • Error rates and status codes

Dashboards (Grafana)

  • Application performance overview
  • Database performance metrics
  • Cache performance monitoring
  • Infrastructure health checks

Logging

  • Structured logging with Pino
  • Configurable log levels
  • Request/response logging
  • Error tracking and stack traces

πŸ—οΈ Project Structure Benefits

Clean Architecture Advantages

  • Testability: Each layer can be tested in isolation with dependency injection
  • Maintainability: Clear separation of concerns and single responsibility
  • Scalability: Easy to add new features without breaking existing code
  • Flexibility: Swap implementations without affecting business logic

Performance Features

  • Connection Pooling: Efficient database connection management
  • Redis Caching: Reduces database load and improves response times
  • gRPC Efficiency: Binary protocol for high-performance communication
  • TypeScript: Compile-time optimization and error prevention

Development Experience

  • Type Safety: Full TypeScript coverage prevents runtime errors
  • Hot Reload: Instant feedback during development
  • Code Quality: Automated formatting and linting
  • Testing: Comprehensive test coverage with fast feedback

🀝 Contributing

Development Workflow

  1. Architecture: Follow Clean Architecture principles
  2. Types: Use TypeScript for complete type safety
  3. Errors: Implement proper error handling with Either pattern
  4. Caching: Add appropriate caching strategies
  5. Testing: Write tests for each layer (unit, integration, e2e)
  6. Code Quality: Use Biome for formatting and linting

Code Standards

  • Follow the existing domain structure
  • Use dependency injection for external dependencies
  • Implement repository pattern for data access
  • Use value objects for domain primitives
  • Write descriptive commit messages

Pull Request Process

  1. Create feature branch from main
  2. Implement changes following project conventions
  3. Add/update tests for new functionality
  4. Ensure all tests pass and code quality checks pass
  5. Update documentation if needed
  6. Submit pull request with clear description

πŸ“„ License

This project is licensed under the ISC License - see the LICENSE file for details.

πŸ‘¨β€πŸ’» Author

Gustavo Murdiga


Note: This microservice demonstrates production-ready Clean Architecture implementation with practical examples of caching, database access, monitoring, and dual communication protocols (gRPC + HTTP) suitable for enterprise applications.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages