こんにちは、ぷらす(@p1ass)です。
最近、gRPC-Web について調査しているのですが、その際にメタデータ付きのリクエストを送る方法に関するドキュメントが一切ないことに気づきました。
分かってしまえば簡単なのですが、結構つまづいたので紹介します。
なお、サンプルコードは gRPC-Web 公式の Hello World ガイドを使用します。
方法
STEP1 enovy.yaml
のallow_headers
にメタデータの key を設定する
gRPC-Web を使うときは、Envoy または Nginx を通してリクエストをプロキシする必要があります。ドキュメントを見る限り Envoy を使う方が推奨されているっぽいので、Envoy を使ってプロキシサーバを建てます。
envoy.yaml
の cors を設定する部分でallow_headers
に使いたいメタデータ (ex. x-custom-metadata
)を追加します。
これによって、メタデータが消えることなく gRPC サーバまで届きます。
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters: - name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts: - name: local_service
domains: ["*"]
routes: - match: { prefix: "/" }
route:
cluster: greeter_service
max_grpc_timeout: 0s
cors:
allow_origin: - "\*"
allow_methods: GET, PUT, DELETE, POST, OPTIONS
allow_headers: x-custom-metadata # x-custom-metadata を許可する
max_age: "1728000"
enabled: true
http_filters: - name: envoy.grpc_web - name: envoy.cors - name: envoy.router
clusters:
- name: greeter_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
hosts: [{ socket_address: { address: localhost, port_value: 9090 }}]
STEP2 クライアントサイドでメタデータを付与してリクエストを行う
STEP1 で正しく gRPC サーバまでメタデータが届くようになったので、後はクライアントサイドでメタデータを付与してリクエストを行うだけです。
const { HelloRequest, HelloReply } = require("./helloworld_pb.js");
const { GreeterClient } = require("./helloworld_grpc_web_pb.js");
const client = new GreeterClient("http://localhost:8080");
const request = new HelloRequest();
request.setName("World");
const metadata = { "x-custom-metadata": "metadata-value" };
// メタデータを付与する
client.sayHello(request, metadata, (err, response) => {
console.log(response.getMessage());
});
まとめ
gRPC-Web はまだまだ発展途上で情報も少ないですが、確実に使えるものになってきていると思います。
ちらほらとプロダクションで使っているという話を聞く機会も増えてきましたし、皆さんも積極的に使っていきましょう 💪