ぷらすのブログ

gRPC-Webでメタデータ付きのリクエストを送信する

#開発#gRPC-Web#Go

こんにちは、ぷらす(@p1ass)です。

最近、gRPC-Web について調査しているのですが、その際にメタデータ付きのリクエストを送る方法に関するドキュメントが一切ないことに気づきました。

分かってしまえば簡単なのですが、結構つまづいたので紹介します。

なお、サンプルコードは gRPC-Web 公式の Hello World ガイドを使用します。

方法

STEP1 enovy.yamlallow_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 はまだまだ発展途上で情報も少ないですが、確実に使えるものになってきていると思います。

ちらほらとプロダクションで使っているという話を聞く機会も増えてきましたし、皆さんも積極的に使っていきましょう 💪

← direnvを使うときは環境変数を.envrcに書くより.envに書いた方が使い勝手が良いLINEの就業型インターンに参加してきた →
Topへ戻る