Overview
The Greeter service is a Go-based microservice that provides greeting functionality while demonstrating service-to-service communication patterns. It calls the Caller service to fetch external API data and stores greeting logs in PostgreSQL.Source code:
services/internal/greeter/service.goEntry point: services/cmd/greeter/main.goTechnology Stack
- Language: Go
- Framework: Connect-Go (gRPC-compatible)
- Database: PostgreSQL via pgx/v5
- Protocol: Protocol Buffers
- Observability: OpenTelemetry
- HTTP Version: HTTP/2 (h2c)
Configuration
Environment Variables
HTTP server port for the greeter service
Base URL for the Caller serviceDocker Compose uses:
http://caller:8081External API URL that the Caller service will fetch
PostgreSQL connection stringExample:
postgresql://devuser:devpass@postgres:5432/greeter_dbOpenTelemetry collector endpoint
Service name for distributed tracing
Docker Compose Configuration
API Reference
Protocol Buffer Definition
The service is defined inproto/greeter/v1/greeter.proto:
Greet RPC
Generates a personalized greeting and fetches external API data via the Caller service.Name to include in the greeting message
The greeting messageFormat:
"Hello {name} from greeter-service!"HTTP status code from the external API call made by Caller service
Size in bytes of the external API response body
Example Request
Example Response
Implementation Details
Service Structure
Fromservices/internal/greeter/service.go:19-33:
Request Flow
- Receive Request: Accept name parameter (defaults to “World”)
- Call External API: Invoke Caller service with timeout
- Error Handling: Map Connect errors and timeouts appropriately
- Generate Response: Format greeting message
- Database Write: Synchronously insert greeting log
- Return Response: Send complete response to client
services/internal/greeter/service.go:35-72:
Timeout Configuration
- RPC Timeout: 2 seconds for Caller service calls
- HTTP Client Timeout: 3 seconds for Connect client
- Server Read Timeout: 5 seconds
- Server Write Timeout: 30 seconds
Database Schema
The service uses agreetings table to log all greeting requests:
Database Pattern
The Greeter service uses a synchronous write pattern:- Database writes complete before sending the response
- Guarantees data persistence
- Adds latency to response time (~1-5ms typically)
- Failures are logged but don’t affect the response
Compare this with the Caller service’s asynchronous pattern where writes happen after the response.
Service Dependencies
Upstream Dependencies
- Caller Service: Required for external API calls
- PostgreSQL: Optional, service runs without DB but won’t persist logs
Downstream Consumers
- Frontend: Via Traefik gateway
- Direct gRPC Clients: Any Connect-compatible client
Error Handling
The service handles multiple error scenarios:Timeout Errors
Code.DEADLINE_EXCEEDED
Caller Service Unavailable
Code.UNAVAILABLE
Database Errors
Database errors are logged but don’t fail the request:Observability
Structured Logging
The service uses Go’sslog package with context-aware logging:
Distributed Tracing
OpenTelemetry instrumentation captures:- RPC call spans
- Service-to-service calls
- Database operations
- Error tracking
Health Checks
Health endpoint at/healthz performs database ping:
Testing
Test the service using grpcurl:Traffic Routing
Traefik routes requests based on the gRPC service path:- CORS: Cross-origin resource sharing
- Auth: JWT validation via auth-service
- Rate Limiting: Prevents abuse
- Retry: Automatic retry on failures
Performance Characteristics
- Latency: ~5-20ms (depends on Caller service + external API)
- Throughput: Limited by database connection pool (default: 10 connections)
- Database Write: Synchronous, adds ~1-5ms
- Timeout Budget: 2 seconds total
Common Issues
Caller Service Unavailable
Error:Code.UNAVAILABLE: caller call failed
Solution: Ensure Caller service is running and accessible at CALLER_BASE_URL
Database Connection Failed
Log:database unavailable, running without DB
Impact: Service runs but doesn’t persist greeting logs
Solution: Check DATABASE_URL and ensure PostgreSQL is accessible
Timeout Errors
Error:Code.DEADLINE_EXCEEDED
Cause: External API call taking >2 seconds
Solution: Increase timeout or investigate external API latency
Related Services
Caller Service
Makes the external API calls for Greeter
Services Overview
Architecture and communication patterns