Introduction
When building gRPC services in .NET, you often need to run common logic across multiple requests, such as logging, authentication checks, or error handling. Writing this logic inside every method can make your code messy and hard to maintain.
This is where gRPC interceptors come in.
In this article, we will understand what interceptors are, how they work, and how to use them effectively in ASP.NET Core in simple and clear language.
What are gRPC Interceptors?
Interceptors in gRPC are similar to middleware in ASP.NET Core.
They allow you to:
Intercept incoming requests before they reach the service
Intercept outgoing responses before they are sent back to the client
Add common logic in one central place
This helps you keep your service methods clean and focused only on business logic.
How Interceptors Work Internally
When a request is sent to a gRPC service, it goes through a pipeline.
First, interceptors get a chance to process the request
Then, the actual service method is executed
After that, the response passes back through interceptors
This means interceptors can run logic both before and after the service method.
Types of Interceptors in gRPC
In .NET, you can use interceptors for different types of calls:
Each type has its own handler method in the interceptor class.
Creating a Basic Interceptor
Let’s create a simple logging interceptor.
public class LoggingInterceptor : Interceptor
{
public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
TRequest request,
ServerCallContext context,
UnaryServerMethod<TRequest, TResponse> continuation)
{
Console.WriteLine("Request received");
var response = await continuation(request, context);
Console.WriteLine("Response sent");
return response;
}
}
Here’s what is happening:
Registering an Interceptor
To use the interceptor, register it in your application.
builder.Services.AddGrpc(options =>
{
options.Interceptors.Add<LoggingInterceptor>();
});
Now, this interceptor will run for all gRPC calls.
Using Interceptors for Authentication
Interceptors are commonly used for authentication.
public class AuthInterceptor : Interceptor
{
public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
TRequest request,
ServerCallContext context,
UnaryServerMethod<TRequest, TResponse> continuation)
{
var token = context.RequestHeaders.FirstOrDefault(h => h.Key == "authorization")?.Value;
if (string.IsNullOrEmpty(token))
{
throw new RpcException(new Status(StatusCode.Unauthenticated, "Token missing"));
}
return await continuation(request, context);
}
}
This ensures that every request is validated before reaching the service.
Using Interceptors for Error Handling
You can also use interceptors for centralized error handling.
public class ExceptionInterceptor : Interceptor
{
public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
TRequest request,
ServerCallContext context,
UnaryServerMethod<TRequest, TResponse> continuation)
{
try
{
return await continuation(request, context);
}
catch (Exception)
{
throw new RpcException(new Status(StatusCode.Internal, "Something went wrong"));
}
}
}
This avoids repeating try-catch blocks in every service method.
Chaining Multiple Interceptors
You can register multiple interceptors.
builder.Services.AddGrpc(options =>
{
options.Interceptors.Add<LoggingInterceptor>();
options.Interceptors.Add<AuthInterceptor>();
});
They will execute in the order they are registered.
Best Practices for Using Interceptors
Keep interceptors focused on a single responsibility
Avoid heavy processing inside interceptors
Use them for cross-cutting concerns like logging and security
Do not put business logic inside interceptors
Following these practices keeps your code clean and maintainable.
Common Mistakes to Avoid
Adding too much logic inside interceptors
Not handling exceptions properly
Forgetting to register interceptors
Avoiding these mistakes will help you use interceptors effectively.
When Should You Use Interceptors?
You should use interceptors when you need:
Logging across all requests
Authentication and authorization checks
Error handling
Request/response modification
They are very useful in large applications with multiple services.
Summary
gRPC interceptors in .NET are a powerful way to handle cross-cutting concerns like logging, authentication, and error handling in a centralized way. They work like middleware and allow you to intercept requests and responses. By using interceptors properly, you can keep your service methods clean, improve maintainability, and build scalable applications.