This example demonstrates how to structure and organize interceptors in a Goa service. It provides skeleton implementations that show the basic patterns for both client-side and server-side interceptors. Note that these are educational examples and not production-ready implementations.
The example shows how to organize different types of interceptors:
// Example interceptor chain - implementations are skeleton/logging only
ServerInterceptor(TraceRequest) // Shows where to add trace context
ServerInterceptor(RequestAudit) // Shows where to add timing/logging
ServerInterceptor(JWTAuth) // Shows where to add auth checks
ServerInterceptor(SetDeadline) // Shows where to add timeouts
ServerInterceptor(Cache) // Shows where to add caching// Example client interceptors - implementations are skeleton/logging only
ClientInterceptor(EncodeTenant) // Shows where to modify auth tokens
ClientInterceptor(Retry) // Shows where to add retry logicThe example shows common interceptor patterns (note: implementations are skeleton only):
-
Authentication Pattern
- Where to add JWT token validation
- How to pass tenant information
- Structure for auth checks
-
Observability Pattern
- Where to add request tracing
- How to structure audit logging
- Points for adding metrics
-
Caching Pattern
- Where to add cache checks
- Structure for cache updates
- Points for cache invalidation
-
Resilience Pattern
- Where to add timeouts
- Structure for retry logic
- Error handling points
-
Start the service:
./run-service.sh
This builds and starts both the service and CLI on port 8088.
-
In another terminal, run the demo:
./demo.sh
The demo script shows the interceptor chain in action with test scenarios:
-
Basic Request Flow
# Shows the complete interceptor chain with logging interceptors-cli create --tenant-id <UUID> --auth "Bearer <token>"
-
Cache Structure
# Shows where cache checks would happen interceptors-cli get --record-id <UUID> --tenant-id <UUID> --auth "Bearer <token>"
-
Retry Pattern
# Shows where retry logic would be implemented interceptors-cli get --record-id "00000000-0000-0000-0000-000000000000"
-
Timeout Pattern
# Shows where deadline handling would occur interceptors-cli get --record-id "00000000-0000-0000-0000-000000000001"
-
Auth Pattern
# Shows where token validation would happen interceptors-cli get --record-id <UUID> --auth "Bearer wrong-token"
The interceptors in this example are skeleton implementations that only log their execution. They demonstrate:
- How to structure interceptors in the design
- Where to place different types of middleware logic
- How to chain interceptors in a specific order
- How client and server interceptors interact
Key Files:
design/design.go: Shows how to define interceptors in Goa DSLinterceptors/interceptors_server.go: Shows server interceptor structureinterceptors/interceptors_client.go: Shows client interceptor structuredemo.sh: Shows how to test interceptor patterns
The service runs on both HTTP on http://localhost:8088 and gRPC on localhost:8080.
The HTTP service provides two endpoints:
POST /records/{tenantID}- Create a new recordGET /records/{tenantID}/{recordID}- Retrieve a record by ID
Each endpoint is protected by various interceptors that demonstrate different aspects of the middleware functionality.