grpc-javaのClientでHeaderをセットしてリクエストする方法をまとめる


gRPCのClientで認証ヘッダーなどリクエストHeaderに値をセットしてgRPC Serverへリクエストするにはどうすればよいか?今回のエントリではgrpc-javaのClientでHeaderをセットしてリクエストする方法をまとめていく。

これまでのエントリではgRPC ServerのほうでClientからリクエストされたHeaderを参照する方法に ServerInterceptorを用いることをまとめてきた。

gRPC ServerのExceptionFilterの方法をまとめた(grpc-java) - 平日インプット週末アウトプットぶろぐ

Clientでも同様にInterceptorを用いてリクエストHeaderに値をセットすることになる。ClientInterceptorを継承したAuthInterceptorを用意する。

ClientInterceptorを準備する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class AuthInterceptor : ClientInterceptor {

    private val CUSTOM_HEADER_KEY = Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER)
    private val AUTH_TOKEN = "your-auth-token"

    override fun <ReqT : Any?, RespT : Any?> interceptCall(method: MethodDescriptor<ReqT, RespT>?, callOptions: CallOptions?, next: Channel?): ClientCall<ReqT, RespT> {
        return object : ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next?.newCall(method, callOptions)) {

            override fun start(responseListener: ClientCall.Listener<RespT>, headers: Metadata) {
                /* put custom header */
                headers.put(CUSTOM_HEADER_KEY, AUTH_TOKEN)
                super.start(object : ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) {
                    override fun onHeaders(headers: Metadata) {
                        super.onHeaders(headers)
                    }
                }, headers)
            }
        }
    }
}

これでauthorizationをキーにした認証ヘッダーをセットするAuthInterceptorができた。

ManagedChannelのビルド工程にinterceptorをセットする

gRPC ClientではManagedChannelをビルドすることになるが、ビルドアップのパラメータにinterceptがある。これに先ほど作ったAuthInterceptorをセットすれば良い。

1
2
3
4
5
6
7
8
9
private fun getNettyChannel(): ManagedChannel {
    return NettyChannelBuilder
            .forAddress(DOMAIN, PORT)
            .sslContext(
                    GrpcSslContexts.forClient()
                            .trustManager(File(CERT_PATH)).build())
            .intercept(AuthInterceptor())
            .build()
}

まとめ

コード

コードはgithubに置いています。

参考になるコードはこちら