<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>RPC | みんたく</title>
	<atom:link href="https://mintaku-blog.net/category/develop/rpc/feed/" rel="self" type="application/rss+xml" />
	<link>https://mintaku-blog.net</link>
	<description>みんたくの技術ブログ</description>
	<lastBuildDate>Sun, 21 Jun 2020 03:13:36 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.11</generator>

<image>
	<url>https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2018/06/cropped-ipad-820272_640.jpg?fit=32%2C32&#038;ssl=1</url>
	<title>RPC | みんたく</title>
	<link>https://mintaku-blog.net</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">144480658</site>	<item>
		<title>Node.jsでgRPC-Webのチュートリアルを試してみた</title>
		<link>https://mintaku-blog.net/grpc-node/</link>
					<comments>https://mintaku-blog.net/grpc-node/#respond</comments>
		
		<dc:creator><![CDATA[みんたく]]></dc:creator>
		<pubDate>Sun, 21 Jun 2020 14:07:34 +0000</pubDate>
				<category><![CDATA[Node.js]]></category>
		<category><![CDATA[RPC]]></category>
		<guid isPermaLink="false">https://mintaku-blog.net/?p=1523</guid>

					<description><![CDATA[<p>こちらを参考にgRPC-Webを使ってHello! Worldを表示するチュートリアルをやってみました。 参考：https://github.com/grp …</p>
The post <a href="https://mintaku-blog.net/grpc-node/">Node.jsでgRPC-Webのチュートリアルを試してみた</a> first appeared on <a href="https://mintaku-blog.net">みんたく</a>.]]></description>
										<content:encoded><![CDATA[<p>こちらを参考にgRPC-Webを使ってHello! Worldを表示するチュートリアルをやってみました。</p>
<p>参考：<a href="https://github.com/grpc/grpc-web/tree/master/net/grpc/gateway/examples/helloworld" target="_blank" rel="noopener noreferrer">https://github.com/grpc/grpc-web/tree/master/net/grpc/gateway/examples/helloworld</a></p>
<h2>全体構成</h2>
<p><img data-attachment-id="1524" data-permalink="https://mintaku-blog.net/grpc-node/img_2809/" data-orig-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/IMG_2809-scaled-e1591579474645.jpg?fit=2560%2C940&amp;ssl=1" data-orig-size="2560,940" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="IMG_2809" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/IMG_2809-scaled-e1591579474645.jpg?fit=300%2C110&amp;ssl=1" data-large-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/IMG_2809-scaled-e1591579474645.jpg?fit=800%2C294&amp;ssl=1" loading="lazy" class="aligncenter wp-image-1524 size-large" src="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/IMG_2809-scaled-e1591579474645-1024x376.jpg?resize=800%2C294&#038;ssl=1" alt="" width="800" height="294" srcset="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/IMG_2809-scaled-e1591579474645.jpg?resize=1024%2C376&amp;ssl=1 1024w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/IMG_2809-scaled-e1591579474645.jpg?resize=300%2C110&amp;ssl=1 300w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/IMG_2809-scaled-e1591579474645.jpg?resize=768%2C282&amp;ssl=1 768w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/IMG_2809-scaled-e1591579474645.jpg?resize=1536%2C564&amp;ssl=1 1536w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/IMG_2809-scaled-e1591579474645.jpg?resize=2048%2C752&amp;ssl=1 2048w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/IMG_2809-scaled-e1591579474645.jpg?w=1600&amp;ssl=1 1600w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/IMG_2809-scaled-e1591579474645.jpg?w=2400&amp;ssl=1 2400w" sizes="(max-width: 800px) 100vw, 800px" data-recalc-dims="1" /></p>
<p>今回のgRPC-Webを使ったHello! Worldを表示するための全体構成はこののようになります。</p>
<p>gRPC-Webでは、gRPCの呼び出しに変換する必要があり、Envoyプロキシを通して実現しています。</p>
<p><span style="font-size: 8px;">参考：<a href="https://qiita.com/betchi/items/0e9040f21b1f8ecbf321" target="_blank" rel="noopener noreferrer">https://qiita.com/betchi/items/0e9040f21b1f8ecbf321</a></span></p>
<p><span style="font-size: 8px;">参考：<a href="https://blog.envoyproxy.io/envoy-and-grpc-web-a-fresh-new-alternative-to-rest-6504ce7eb880" target="_blank" rel="noopener noreferrer">https://blog.envoyproxy.io/envoy-and-grpc-web-a-fresh-new-alternative-to-rest-6504ce7eb880</a></span></p>
<p><span style="font-size: 8px;">参考：<a href="https://qiita.com/namusyaka/items/71cf27fd3242adbf348c" target="_blank" rel="noopener noreferrer">https://qiita.com/namusyaka/items/71cf27fd3242adbf348c</a></span></p>
<p>&nbsp;</p>
<h2>Protocol BuffersでgRPCサービスを定義する</h2>
<p>ここではRPCメソッド、リクエスト、レスポンスを持つサービスを定義します。</p>
<p>・helloworld.proto</p><pre class="crayon-plain-tag">syntax = "proto3";

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}</pre><p>&nbsp;</p>
<h2>Node.jsでgRPCサービスを実装</h2>
<p>次に、Node.jsでgRPCサービスを実装します。ここでは、クライアントからリクエストを受け取り、call.request.nameを介してメッセージフィールドにアクセスできます。その後、レスポンスを作成し、クライアントに送り返します。</p>
<p>・server.js</p><pre class="crayon-plain-tag">const PROTO_PATH = __dirname + '/helloworld.proto';

const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
const packageDefinition = protoLoader.loadSync(
  PROTO_PATH,
  {
    keepCase: true,
    longs: String,
    enums: String,
    defaults: true,
    oneofs: true
  }
);
const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
const helloworld = protoDescriptor.helloworld;

function doSayHello(call, callback) {
  callback(null, {
    message: 'Hello! ' + call.request.name
  });
}

function getServer() {
  const server = new grpc.Server();
  server.addService(helloworld.Greeter.service, {
    sayHello: doSayHello,
  });
  return server;
}

if (require.main === module) {
  const server = getServer();
  server.bind('0.0.0.0:9090', grpc.ServerCredentials.createInsecure());
  server.start();
}

exports.getServer = getServer;</pre><p>&nbsp;</p>
<h2>Envoyプロキシの設定</h2>
<p>次に、ブラウザのgRPC-Webリクエストをバックエンドに転送するようにEnvoyプロキシを構成する必要があります。ここでは、ポート:8080でリッスンするようにEnvoyを構成し、ポート:9090でクラスターにgRPC-Webリクエストを転送します。</p>
<p>・envoy.yaml</p><pre class="crayon-plain-tag">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_string_match:
                - prefix: "*"
                allow_methods: GET, PUT, DELETE, POST, OPTIONS
                allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
                max_age: "1728000"
                expose_headers: custom-header-1,grpc-status,grpc-message
          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 }}]</pre><p>&nbsp;</p>
<h2>Envoy用Dockerfileの作成</h2>
<p>Envoyを起動させるためにDockerfileを作成します。</p>
<p>・envoy.Dockerfile</p><pre class="crayon-plain-tag">FROM envoyproxy/envoy:v1.14.1
COPY ./envoy.yaml /etc/envoy/envoy.yaml
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml</pre><p>&nbsp;</p>
<h2>クライアントコードの作成</h2>
<p>HelloRequest、HelloReplyおよびGreeterClientクラスをインポートするファイルは、前に定義したprotocジェネレータによって生成されます(後で生成します)。</p>
<p>GreeterClientクラスをインスタンス化し、HelloRequestprotobufオブジェクトにフィールドを設定します。ファイルで定義したのと同じように、client.sayHello()を介してgRPC呼び出しを行うことができます。</p>
<p>・client.js</p><pre class="crayon-plain-tag">const {HelloRequest, HelloReply} = require('./helloworld_pb.js');
const {GreeterClient} = require('./helloworld_grpc_web_pb.js');

var client = new GreeterClient('http://localhost:8080');

var request = new HelloRequest();
request.setName('World');

client.sayHello(request, {}, (err, response) =&gt; {
  console.log(response.getMessage());
});</pre><p>&nbsp;</p>
<h2>package.jsonの作成</h2>
<p>package.jsonを作成します。</p>
<p>・package.json</p><pre class="crayon-plain-tag">{
  "name": "grpc-web-simple-example",
  "version": "0.1.0",
  "description": "gRPC-Web simple example",
  "devDependencies": {
    "@grpc/proto-loader": "~0.5.4",
    "async": "~1.5.2",
    "google-protobuf": "~3.12.0",
    "grpc": "~1.24.2",
    "grpc-web": "~1.1.0",
    "lodash": "~4.17.0",
    "webpack": "~4.43.0",
    "webpack-cli": "~3.3.11"
  }
}</pre><p>&nbsp;</p>
<h2>index.htmlの作成</h2>
<p>最後にindex.htmlを作成します。</p>
<p>・index.html</p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;gRPC-Web Example&lt;/title&gt;
    &lt;script src="./dist/main.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;Open up the developer console and see the logs for the output.&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre><p>&nbsp;</p>
<p>最終的に作成・生成したファイルは以下のようになりました。</p>
<p><img data-attachment-id="1525" data-permalink="https://mintaku-blog.net/grpc-node/%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2020-06-07-17-40-16/" data-orig-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/356d8ae48c95ad220206dfe449ac8c6f.png?fit=526%2C508&amp;ssl=1" data-orig-size="526,508" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="スクリーンショット 2020-06-07 17.40.16" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/356d8ae48c95ad220206dfe449ac8c6f.png?fit=300%2C290&amp;ssl=1" data-large-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/356d8ae48c95ad220206dfe449ac8c6f.png?fit=526%2C508&amp;ssl=1" loading="lazy" class="aligncenter size-full wp-image-1525" src="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/356d8ae48c95ad220206dfe449ac8c6f.png?resize=526%2C508&#038;ssl=1" alt="" width="526" height="508" srcset="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/356d8ae48c95ad220206dfe449ac8c6f.png?w=526&amp;ssl=1 526w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/356d8ae48c95ad220206dfe449ac8c6f.png?resize=300%2C290&amp;ssl=1 300w" sizes="(max-width: 526px) 100vw, 526px" data-recalc-dims="1" /></p>
<p>&nbsp;</p>
<h2>Protobufメッセージとクライアントサービススタブの生成</h2>
<h3>protocのインストール</h3>
<p>こちらを参考にprotocをインストールします。</p>
<p><a href="https://github.com/protocolbuffers/protobuf/releases" target="_blank" rel="noopener noreferrer">https://github.com/protocolbuffers/protobuf/releases</a></p>
<p>以下でインストールされたか確認します。</p><pre class="crayon-plain-tag">$ which protoc
/usr/local/bin/protoc</pre><p></p>
<h3>protoc-gen-grpc-webのインストール</h3>
<p>こちらからprotoc-gen-grpc-web-1.1.0-darwin-x86_64をダウンロードし、パスを通します。</p>
<p><a href="https://github.com/grpc/grpc-web/releases" target="_blank" rel="noopener noreferrer">https://github.com/grpc/grpc-web/releases</a></p><pre class="crayon-plain-tag">$ sudo mv ~/Downloads/protoc-gen-grpc-web-1.1.0-darwin-x86_64 \
/usr/local/bin/protoc-gen-grpc-web</pre><p></p><pre class="crayon-plain-tag">$ chmod +x /usr/local/bin/protoc-gen-grpc-web</pre><p>protocとprotoc-gen-grpc-webのインストールが完了したら、以下のコマンドでjsファイルを生成します。</p><pre class="crayon-plain-tag">$ protoc -I=. helloworld.proto \
--js_out=import_style=commonjs:. \
--grpc-web_out=import_style=commonjs,mode=grpcwebtext:.</pre><p>以下の2つのファイルが生成されたことを確認します。</p>
<ul>
<li>helloworld_pb.js: HelloRequestとHelloReplyクラスが含まれたファイル</li>
<li>helloworld_grpc_web_pb.js: GreeterClientクラスが含まれたファイル</li>
</ul>
<p>protoc-gen-grpc-web: program not found or is not executableのエラーが出た場合は、こちらを参考にしてください。</p>
<p><a href="https://hsuzuki.hatenablog.com/entry/2018/10/30/184544" target="_blank" rel="noopener noreferrer">https://hsuzuki.hatenablog.com/entry/2018/10/30/184544</a></p>
<h3>クライアントのjsコードをコンパイル</h3>
<p>クラインとのjsコードをブラウザが認識できるようにコンパイルします。webpackでclient.jsがビルドされdist/main.jsが生成されます。</p><pre class="crayon-plain-tag">$ npm install</pre><p></p><pre class="crayon-plain-tag">$ npx webpack client.js --mode development</pre><p>&nbsp;</p>
<h2>実際に動かしてみる</h2>
<p>以上でサンプルを動かす準備は整いました。gRPCサービス、Envoyプロキシ、クライアントをそれぞれ立ち上げます。</p>
<p>gRPCサービス(ポート:9090リッスン)を立ち上げます。</p><pre class="crayon-plain-tag">$ node server.js</pre><p>次にEnvoyプロキシを実行します。このenvoy.yamlファイルは、ポート:8080でリッスンし、転送するようにEnvoyを構成します。</p><pre class="crayon-plain-tag">$ docker build -t helloworld / envoy -f ./envoy.Dockerfile .</pre><p></p><pre class="crayon-plain-tag">$ docker run -d -p 8080：8080 -p 9901：9901 helloworld / envoy</pre><p>最後にwebサーバを立ち上げます。</p><pre class="crayon-plain-tag">$ python3 -m http.server 8081</pre><p>全て正常に立ち上げたらlocalhost:8081にアクセスします。</p>
<p>デベロッパーツールからコンソールを立ち上げるとHello! Worldと表示されていることが確認できます。</p>
<p><img data-attachment-id="1527" data-permalink="https://mintaku-blog.net/grpc-node/%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2020-06-07-17-32-47/" data-orig-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/24eb438664b042c469988fcdc1aef6f3.png?fit=2036%2C212&amp;ssl=1" data-orig-size="2036,212" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="スクリーンショット 2020-06-07 17.32.47" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/24eb438664b042c469988fcdc1aef6f3.png?fit=300%2C31&amp;ssl=1" data-large-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/24eb438664b042c469988fcdc1aef6f3.png?fit=800%2C84&amp;ssl=1" loading="lazy" class="aligncenter size-large wp-image-1527" src="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/24eb438664b042c469988fcdc1aef6f3.png?resize=800%2C84&#038;ssl=1" alt="" width="800" height="84" srcset="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/24eb438664b042c469988fcdc1aef6f3.png?resize=1024%2C107&amp;ssl=1 1024w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/24eb438664b042c469988fcdc1aef6f3.png?resize=300%2C31&amp;ssl=1 300w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/24eb438664b042c469988fcdc1aef6f3.png?resize=768%2C80&amp;ssl=1 768w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/24eb438664b042c469988fcdc1aef6f3.png?resize=1536%2C160&amp;ssl=1 1536w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/24eb438664b042c469988fcdc1aef6f3.png?w=2036&amp;ssl=1 2036w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/24eb438664b042c469988fcdc1aef6f3.png?w=1600&amp;ssl=1 1600w" sizes="(max-width: 800px) 100vw, 800px" data-recalc-dims="1" /></p>
<p>&nbsp;</p>
<p>client.jsのsetNameをTestにして再度ビルドするとちゃんとHello! Testに変わっていることが確認できます。</p><pre class="crayon-plain-tag">request.setName('Test');</pre><p><img data-attachment-id="1530" data-permalink="https://mintaku-blog.net/grpc-node/%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2020-06-07-17-34-47/" data-orig-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/f5e23bae93919fbea256b7cc9e822237.png?fit=2344%2C192&amp;ssl=1" data-orig-size="2344,192" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="スクリーンショット 2020-06-07 17.34.47" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/f5e23bae93919fbea256b7cc9e822237.png?fit=300%2C25&amp;ssl=1" data-large-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/f5e23bae93919fbea256b7cc9e822237.png?fit=800%2C66&amp;ssl=1" loading="lazy" class="aligncenter size-large wp-image-1530" src="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/f5e23bae93919fbea256b7cc9e822237.png?resize=800%2C66&#038;ssl=1" alt="" width="800" height="66" srcset="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/f5e23bae93919fbea256b7cc9e822237.png?resize=1024%2C84&amp;ssl=1 1024w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/f5e23bae93919fbea256b7cc9e822237.png?resize=300%2C25&amp;ssl=1 300w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/f5e23bae93919fbea256b7cc9e822237.png?resize=768%2C63&amp;ssl=1 768w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/f5e23bae93919fbea256b7cc9e822237.png?resize=1536%2C126&amp;ssl=1 1536w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/f5e23bae93919fbea256b7cc9e822237.png?resize=2048%2C168&amp;ssl=1 2048w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/f5e23bae93919fbea256b7cc9e822237.png?w=1600&amp;ssl=1 1600w" sizes="(max-width: 800px) 100vw, 800px" data-recalc-dims="1" /></p>
<p>&nbsp;</p>
<h2>便利な拡張機能</h2>
<p><img data-attachment-id="1526" data-permalink="https://mintaku-blog.net/grpc-node/%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2020-06-07-17-38-09/" data-orig-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/5557207d762900d69fea40824623644a.png?fit=1162%2C612&amp;ssl=1" data-orig-size="1162,612" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="スクリーンショット 2020-06-07 17.38.09" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/5557207d762900d69fea40824623644a.png?fit=300%2C158&amp;ssl=1" data-large-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/5557207d762900d69fea40824623644a.png?fit=800%2C421&amp;ssl=1" loading="lazy" class="aligncenter size-large wp-image-1526" src="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/5557207d762900d69fea40824623644a.png?resize=800%2C421&#038;ssl=1" alt="" width="800" height="421" srcset="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/5557207d762900d69fea40824623644a.png?resize=1024%2C539&amp;ssl=1 1024w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/5557207d762900d69fea40824623644a.png?resize=300%2C158&amp;ssl=1 300w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/5557207d762900d69fea40824623644a.png?resize=768%2C404&amp;ssl=1 768w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2020/06/5557207d762900d69fea40824623644a.png?w=1162&amp;ssl=1 1162w" sizes="(max-width: 800px) 100vw, 800px" data-recalc-dims="1" /></p>
<p>こちらのChrome拡張機能を使うことでgRPCサーバーから返されたリクエスト、レスポンス、エラーオブジェクトのデシリアライズされたJSONが表示されるようになります。</p>
<p><a href="https://chrome.google.com/webstore/detail/grpc-web-developer-tools/ddamlpimmiapbcopeoifjfmoabdbfbjj/related?hl=en" target="_blank" rel="noopener noreferrer">https://chrome.google.com/webstore/detail/grpc-web-developer-tools/ddamlpimmiapbcopeoifjfmoabdbfbjj/related?hl=en</a></p>The post <a href="https://mintaku-blog.net/grpc-node/">Node.jsでgRPC-Webのチュートリアルを試してみた</a> first appeared on <a href="https://mintaku-blog.net">みんたく</a>.]]></content:encoded>
					
					<wfw:commentRss>https://mintaku-blog.net/grpc-node/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1523</post-id>	</item>
	</channel>
</rss>
