Go言語でgRPCに入門してみた3 独自インターセプタ

以前の記事で、gRPCで認証処理を入れる実験をしてみました。
その時はこちら

インターセプタには認証の他にもロギングなど、定型的な処理がすでに用意されていていて便利そうです。
ただ、実際の業務では独自処理を差し挟むこともあるかと思い、この記事ではカスタムインターセプタのテストをやってみました。
railsのbefore、afterやjavaのSpringのinterceptorに慣れている人であれば、すぐにイメージがつくと思います。

この記事では前々回の名前を渡すとhello <name>を返却するだけのサンプルに以下のことをやるカスタムインターセプタを追加します。
前々回の記事はこちら

* 送信された名前を<<< >>>で囲みます
* 返却したhelloを*** ***で囲みます

例:name: worldをサーバに送信すると"*** hello ***<<< world >>>"を返却


独自インターセプタを追加

server.goに以下のような関数を定義します。
これが独自インターセプタの処理内容となります。
関数の真ん中にあるhandler()がリクエストを受けて起動される本来の処理です。

func CustomInterceptor() grpc.UnaryServerInterceptor {
   return func(ctx context.Context, request interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHand
       fmt.Printf("before process")
       helloMessage, _ := request.(*hello.HelloMessage)
       helloMessage.Name = fmt.Sprintf("<<< %s >>>", helloMessage.Name)
       
       res, err := handler(ctx, request)
       if err != nil {
           return nil, err
       }
       
       fmt.Println("after process")       
       helloResponse, _ := res.(*hello.HelloResponse)
       helloResponse.Msg = fmt.Sprintf("*** %s ***", helloResponse.Msg)
       return res, nil
   }
}

独自インターセプタを設定する

server.goの以下の部分を変更します。
リクエストの度に処理を行いたいインターセプタをこのように登録します。

   server := grpc.NewServer(
       grpc.UnaryInterceptor(CustomInterceptor()),
   )

コード全文

下がserver.goのコード全文となります。

package main
import (
	"context"
	"fmt"
	"log"
	"net"
	"test/hello"
	"google.golang.org/grpc"
)

func main() {
	listenPort, err := net.Listen("tcp", ":19003")
	if err != nil {
		log.Fatal(err)
	}
	server := grpc.NewServer(
		grpc.UnaryInterceptor(CustomInterceptor()),
	)
	hello.RegisterHelloServer(server, &Hello{})
	server.Serve(listenPort)
}

type Hello struct{}

func (h *Hello) Hello(cts context.Context, message *hello.HelloMessage) (*hello.HelloResponse, error) {
	res := hello.HelloResponse{Msg: fmt.Sprintf("hello %s", message.Name)}
	return &res, nil
}

func CustomInterceptor() grpc.UnaryServerInterceptor {
	return func(ctx context.Context, request interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
		fmt.Printf("before process")
		helloMessage, _ := request.(*hello.HelloMessage)
		helloMessage.Name = fmt.Sprintf("<<< %s >>>", helloMessage.Name)

		res, err := handler(ctx, request)
		if err != nil {
			return nil, err
		}

		fmt.Println("after process")
		helloResponse, _ := res.(*hello.HelloResponse)
		helloResponse.Msg = fmt.Sprintf("*** %s ***", helloResponse.Msg)
		return res, nil
	}
}


この記事が気に入ったらサポートをしてみませんか?