DEV Community

Ferdynand Odhiambo
Ferdynand Odhiambo

Posted on

Bridging the gap: From axios to gRPC interceptors in Go

 )

🌟 Introduction

In my previous article on Axios interceptors in Next.js, I explained how to handle tokens, log requests, and catch errors before they hit your actual API call.

Now let’s switch lanes — same logic, different side of the stack.

But wait… gRPC? Go? Interceptors?? Sounds like a Marvel multiverse of concepts. 😅

Fear not! If you’ve used Axios interceptors to attach tokens, handle errors, or log requests, you already understand half the concept.

Let’s explore how interceptors in Go (with gRPC) let you do cool backend ninja stuff, like:

  • Checking if requests are legit (Auth)
  • Logging what’s going on (Observability)
  • Rejecting bad vibes (a.k.a. invalid requests)
  • Making your code cleaner, smarter, and scalable

But First, What’s gRPC (and Why Should I Care)?

TL;DR: gRPC is a fast, efficient way for microservices to talk to each other — think of it like WhatsApp for backend services, but with strict message formats and no blue ticks.

  • Faster than REST
  • Uses Protocol Buffers instead of JSON
  • Strongly typed APIs
  • Supports unary and streaming calls If you’re building microservices in Go, gRPC is your best friend — and interceptors are the middleware party crashers who add their own magic to every request.

Axios vs gRPC Interceptors — Visual Time!

Here’s a mental model:


Just like in Axios, interceptors wrap around your actual logic and let you sneak in helpful behavior before/after your calls.

Let’s Write a Simple gRPC Unary Interceptor

Use Case: You want to reject unauthorized users and log the request path.

func AuthLoggerInterceptor(
    ctx context.Context,
    req interface{},
    info *grpc.UnaryServerInfo,
    handler grpc.UnaryHandler,
) (interface{}, error) {
    log.Println("New gRPC call to:", info.FullMethod)

    md, ok := metadata.FromIncomingContext(ctx)
    if !ok {
        return nil, status.Error(codes.Unauthenticated, "No metadata found!")
    }

    token := md["authorization"]
    if len(token) == 0 || token[0] != "Bearer secret123" {
        log.Println("Invalid token")
        return nil, status.Error(codes.Unauthenticated, "Invalid token!")
    }

    // All good? Forward the request to your actual method
    return handler(ctx, req)
}
Enter fullscreen mode Exit fullscreen mode

Plug It Into Your gRPC Server

server := grpc.NewServer(
    grpc.UnaryInterceptor(AuthLoggerInterceptor),
)
pb.RegisterMyServiceServer(server, &MyService{})
Enter fullscreen mode Exit fullscreen mode

And boom — every single request goes through your interceptor like a VIP security gate.

Bonus: What About Streams?

Just like in Axios you don’t always do GET — in gRPC, you can also stream data (think Netflix but backend-y).

Here’s how to intercept streaming RPCs too:

func StreamLoggerInterceptor(
    srv interface{},
    ss grpc.ServerStream,
    info *grpc.StreamServerInfo,
    handler grpc.StreamHandler,
) error {
    log.Println("Stream call to:", info.FullMethod)
    return handler(srv, ss)
}
Enter fullscreen mode Exit fullscreen mode

And attach it:

server := grpc.NewServer(
    grpc.StreamInterceptor(StreamLoggerInterceptor),
)
Enter fullscreen mode Exit fullscreen mode

Real-World Analogy: Coffee Shop

Imagine your gRPC server is a barista ☕.

You (the client) place an order.

The interceptor is the cashier who:

  • Checks your loyalty card (auth)
  • Writes your name wrong on the cup (logging lol)
  • Decides if you deserve a coffee today (validation)
  • Then your order goes to the barista (actual service logic).

That’s literally what interceptors do.

🎯 Why Should You Care?

  • Centralized logic — no need to sprinkle "check token" in every service method
  • Cleaner services — your actual gRPC methods stay focused
  • Cross-cutting concerns — logging, monitoring, and error handling become a breeze
  • Scalable AF — perfect for microservices that need to stay DRY and consistent

Want to Learn More?

Here are some golden nuggets to level up your Go + gRPC knowledge:

Wrapping Up

If you’ve already mastered Axios interceptors on the frontend, using interceptors in Go is just the next logical step. You’re now building the backend side of the same bridge — and it’s strong, fast, and clean. 🧱

Interceptors are your backend middleware ninjas — silent but powerful.

Have questions, feedback, or want to show off your microservice setup? Let’s connect. You can also go back and reread my Axios interceptors article if you need a frontend refresher. 💬

Stay curious. Write clean code. And intercept all the things. 🚀

Top comments (0)