Unary Interceptors
Learn how to implement unary gRPC interceptors for Goa services, with practical examples of common patterns.
Goa services use standard gRPC interceptors, which means you can use any gRPC interceptor that follows the standard pattern. This guide shows you how to create effective gRPC interceptors that work well with Goa services, with examples drawn from real-world usage.
gRPC interceptors should focus on protocol-level concerns like metadata handling, connection management, and message transformation. For business logic and type-safe access to your service’s payloads and results, use Goa interceptors instead. Goa interceptors provide direct access to your service’s domain types and are better suited for business-level concerns.
gRPC supports two types of interceptors, each serving different use cases:
Unary Interceptors: Handle single request/response RPCs, like traditional API calls. These are simpler to implement and are the most common type.
Stream Interceptors: Handle streaming RPCs where either the client, server, or both can send multiple messages. These require more complex handling of the stream lifecycle.
Here are some common scenarios where gRPC interceptors are particularly useful:
When implementing gRPC interceptors for Goa services:
Focus on Protocol Concerns: Use gRPC interceptors for protocol-level operations like metadata handling. Use Goa interceptors for business logic.
Handle Context Properly: Always respect context cancellation and propagate context values correctly.
Be Consistent: Apply the same interceptor patterns across your service for predictable behavior.
Consider Performance: Interceptors run on every request, so keep them efficient.
Error Handling: Use appropriate gRPC status codes and include relevant error details.
Testing: Test interceptors thoroughly, including error cases and context cancellation.
Here’s how to integrate gRPC interceptors with a Goa service:
func main() {
// Create gRPC server with interceptors
srv := grpc.NewServer(
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
// Protocol-level concerns in gRPC interceptors
MetadataInterceptor(),
LoggingInterceptor(),
MonitoringInterceptor(),
)),
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
StreamMetadataInterceptor(),
StreamLoggingInterceptor(),
StreamMonitoringInterceptor(),
)),
)
// Register Goa gRPC server
pb.RegisterServiceServer(srv, server)
}
This example demonstrates:
go-grpc-middleware
package