Overview
The Custom Language Service is a Node.js/Express microservice that provides a simple invocation endpoint with configurable response codes. It’s primarily used for testing error handling, circuit breakers, and retry logic in the Gateway service.Source code:
node-services/custom-lang-service/app.jsEntry point: node-services/custom-lang-service/server.jsTechnology Stack
- Language: Node.js
- Framework: Express
- Database: PostgreSQL via pg driver
- Observability: OpenTelemetry
Configuration
Environment Variables
HTTP server port for the custom language service
PostgreSQL connection stringExample:
postgresql://devuser:devpass@postgres:5432/lang_dbService runs without database if not providedOpenTelemetry collector endpoint
Service name for distributed tracing
Docker Compose Configuration
API Reference
POST /invoke
Invoke the custom language service with a name parameter.Name to include in the response messageSpecial values trigger error responses:
"unauthorized"→ 401 Unauthorized"forbidden"→ 403 Forbidden"notfound"→ 404 Not Found"conflict"→ 409 Conflict"ratelimit"→ 429 Too Many Requests"unavailable"→ 503 Service Unavailable
Success message with the provided nameFormat:
"Hello {name} from custom-lang-service!"Example Request (Success)
Example Response (Success)
Example Request (Error)
Example Response (Error)
GET /healthz
Health check endpoint that verifies database connectivity.Example Request
Example Response (Healthy)
Error Responses
- 503 Service Unavailable: Database health check failed
Implementation Details
Invoke Logic
Fromnode-services/custom-lang-service/app.js:16-69:
Error Response Mapping
| Input Name | HTTP Status | Response Body | Use Case |
|---|---|---|---|
unauthorized | 401 | {"error": "unauthorized"} | Test authentication errors |
forbidden | 403 | {"error": "forbidden"} | Test authorization errors |
notfound | 404 | {"error": "not found"} | Test resource not found |
conflict | 409 | {"error": "conflict"} | Test resource conflicts |
ratelimit | 429 | {"error": "rate limited"} | Test retry logic |
unavailable | 503 | {"error": "service unavailable"} | Test circuit breaker |
| Other | 200 | {"message": "Hello ..."} | Normal operation |
Database Schema
The service uses anexecutions table to log all invocations:
Unlike the Go services, the Node.js services don’t include automatic migrations. You need to create the table manually.
Database Pattern
The service uses a synchronous write pattern:- Database write completes before sending response
- Errors are logged but don’t fail the request
- Records both successful and error responses
Testing Error Scenarios
The service is designed to help test error handling in the Gateway service:Test Circuit Breaker
Trigger consecutive failures to open the circuit:Test Retry Logic
Trigger a retryable error:Test Error Mapping
Verify HTTP status to gRPC code mapping:Service Dependencies
Upstream Dependencies
- PostgreSQL: Optional, service runs without DB but won’t persist logs
Downstream Consumers
- Gateway Service: Primary consumer, uses for demonstrating resilience patterns
Observability
Logging
The service logs database errors:Distributed Tracing
OpenTelemetry instrumentation captures:- HTTP requests
- Database queries
- Response status codes
node-services/custom-lang-service/tracing.js.
Health Checks
Fromnode-services/custom-lang-service/app.js:7-14:
Performance Characteristics
- Latency: ~1-5ms (without database)
- Latency (with DB): ~5-15ms
- Throughput: High (no complex processing)
- Database Write: Synchronous, adds ~5-10ms
- Database Pool: 10 connections
Integration Example
Using the service from the Gateway service:Common Issues
Database Not Configured
Impact: Service runs but doesn’t persist execution logs Solution: SetDATABASE_URL environment variable
Database Table Missing
Error: Database query fails with “relation does not exist” Solution: Create theexecutions table manually:
Gateway Circuit Breaker Not Opening
Symptom: Even after many failures, circuit stays closed Cause: Not enough consecutive failures (need 5+) Solution: Send more consecutive error requests:Use Cases
Development Testing
Test error handling without breaking real services:Load Testing
Test Gateway service resilience under failures:Circuit Breaker Demo
Demonstrate circuit breaker behavior:- Send successful requests → Circuit closed
- Send 5+ failures → Circuit opens
- Wait 30 seconds → Circuit half-open
- Send successful request → Circuit closes
Testing
Test the service directly:Related Services
Gateway Service
Primary consumer with circuit breaker logic
Services Overview
Learn about service architecture