11# gRPC Elixir
22
3+ [ ![ GitHub CI] ( https://github.com/elixir-grpc/grpc/actions/workflows/ci.yml/badge.svg )] ( https://github.com/elixir-grpc/grpc/actions/workflows/ci.yml )
34[ ![ Hex.pm] ( https://img.shields.io/hexpm/v/grpc.svg )] ( https://hex.pm/packages/grpc )
4- [ ![ Travis Status] ( https://app.travis-ci.com/elixir-grpc/grpc.svg?branch=master )] ( https://app.travis-ci.com/elixir-grpc/grpc )
5- [ ![ GitHub actions Status] ( https://github.com/elixir-grpc/grpc/workflows/CI/badge.svg )] ( https://github.com/elixir-grpc/grpc/actions )
5+ [ ![ Hex Docs] ( https://img.shields.io/badge/hex-docs-lightgreen.svg )] ( https://hexdocs.pm/grpc/ )
66[ ![ License] ( https://img.shields.io/hexpm/l/grpc.svg )] ( https://github.com/elixir-grpc/grpc/blob/master/LICENSE.md )
7- [ ![ Last Updated] ( https://img.shields.io/github/last-commit/elixir-grpc/grpc.svg )] ( https://github.com/elixir-grpc/grpc/commits/master )
87[ ![ Total Download] ( https://img.shields.io/hexpm/dt/grpc.svg )] ( https://hex.pm/packages/elixir-grpc/grpc )
8+ [ ![ Last Updated] ( https://img.shields.io/github/last-commit/elixir-grpc/grpc.svg )] ( https://github.com/elixir-grpc/grpc/commits/master )
99
1010An Elixir implementation of [ gRPC] ( http://www.grpc.io/ ) .
1111
1212## Table of contents
1313
1414- [ Installation] ( #installation )
1515- [ Usage] ( #usage )
16+ - [ Simple RPC] ( #simple-rpc )
17+ - [ HTTP Transcoding] ( #http-transcoding )
18+ - [ Start Application] ( #start-application )
1619- [ Features] ( #features )
1720- [ Benchmark] ( #benchmark )
1821- [ Contributing] ( #contributing )
@@ -24,20 +27,49 @@ The package can be installed as:
2427 ``` elixir
2528 def deps do
2629 [
27- {:grpc , " ~> 0.7" },
28- # We don't force protobuf as a dependency for more
29- # flexibility on which protobuf library is used,
30- # but you probably want to use it as well
31- {:protobuf , " ~> 0.11" }
30+ {:grpc , " ~> 0.8" }
3231 ]
3332 end
3433 ```
3534
3635## Usage
3736
38- 1 . Generate Elixir code from proto file as [ protobuf-elixir] ( https://github.com/tony612/protobuf-elixir#usage ) shows(especially the ` gRPC Support ` section).
37+ 1 . Write your protobuf file:
38+
39+ ``` protobuf
40+ syntax = "proto3";
41+
42+ package helloworld;
3943
40- 2 . Implement the server side code like below and remember to return the expected message types.
44+ // The request message containing the user's name.
45+ message HelloRequest {
46+ string name = 1;
47+ }
48+
49+ // The response message containing the greeting
50+ message HelloReply {
51+ string message = 1;
52+ }
53+
54+ // The greeting service definition.
55+ service Greeter {
56+ // Greeting function
57+ rpc SayHello (HelloRequest) returns (HelloReply) {}
58+ }
59+
60+ ```
61+
62+ 2 . Then generate Elixir code from proto file as [ protobuf-elixir] ( https://github.com/tony612/protobuf-elixir#usage ) shows (especially the ` gRPC Support ` section) or using [ protobuf_generate] ( https://hex.pm/packages/protobuf_generate ) hex package. Example using ` protobuf_generate ` lib:
63+
64+ ``` shell
65+ mix protobuf.generate --output-path=./lib --include-path=./priv/protos helloworld.proto
66+ ```
67+
68+ In the following sections you will see how to implement gRPC server logic.
69+
70+ ### ** Simple RPC**
71+
72+ 1 . Implement the server side code like below and remember to return the expected message types.
4173
4274``` elixir
4375defmodule Helloworld .Greeter .Server do
@@ -50,9 +82,7 @@ defmodule Helloworld.Greeter.Server do
5082end
5183```
5284
53- 3 . Start the server
54-
55- You can start the gRPC server as a supervised process. First, add ` GRPC.Server.Supervisor ` to your supervision tree.
85+ 2 . Define gRPC endpoints
5686
5787``` elixir
5888# Define your endpoint
@@ -62,7 +92,86 @@ defmodule Helloworld.Endpoint do
6292 intercept GRPC .Server .Interceptors .Logger
6393 run Helloworld .Greeter .Server
6494end
95+ ```
96+
97+ We will use this module [ in the gRPC server startup section] ( #start-application ) .
98+
99+ ** __ Note:__ ** For other types of RPC call like streams see [ here] ( interop/lib/interop/server.ex ) .
100+
101+ ### ** HTTP Transcoding**
102+
103+ 1 . Adding [ grpc-gateway annotations] ( https://cloud.google.com/endpoints/docs/grpc/transcoding ) to your protobuf file definition:
104+
105+ ``` protobuf
106+ import "google/api/annotations.proto";
107+ import "google/protobuf/timestamp.proto";
108+
109+ package helloworld;
65110
111+ // The greeting service definition.
112+ service Greeter {
113+ // Sends a greeting
114+ rpc SayHello (HelloRequest) returns (HelloReply) {
115+ option (google.api.http) = {
116+ get: "/v1/greeter/{name}"
117+ };
118+ }
119+
120+ rpc SayHelloFrom (HelloRequestFrom) returns (HelloReply) {
121+ option (google.api.http) = {
122+ post: "/v1/greeter"
123+ body: "*"
124+ };
125+ }
126+ }
127+ ```
128+
129+ 2 . Add protoc plugin dependency and compile your protos using [ protobuf_generate] ( https://github.com/drowzy/protobuf_generate ) hex [ package] ( https://hex.pm/packages/protobuf_generate ) :
130+
131+ In mix.exs:
132+
133+ ``` elixir
134+ def deps do
135+ [
136+ {:grpc , " ~> 0.7" },
137+ {:protobuf_generate , " ~> 0.1.1" }
138+ ]
139+ end
140+ ```
141+
142+ And in your terminal:
143+
144+ ``` shell
145+ mix protobuf.generate \
146+ --include-path=priv/proto \
147+ --include-path=deps/googleapis \
148+ --generate-descriptors=true \
149+ --output-path=./lib \
150+ --plugins=ProtobufGenerate.Plugins.GRPCWithOptions \
151+ google/api/annotations.proto google/api/http.proto helloworld.proto
152+ ```
153+
154+ 3 . Enable http_transcode option in your Server module
155+ ``` elixir
156+ defmodule Helloworld .Greeter .Server do
157+ use GRPC .Server ,
158+ service: Helloworld .Greeter .Service ,
159+ http_transcode: true
160+
161+ @spec say_hello (Helloworld .HelloRequest .t , GRPC .Server .Stream .t ) :: Helloworld .HelloReply .t
162+ def say_hello (request, _stream ) do
163+ %Helloworld .HelloReply {message: " Hello #{ request.name } " }
164+ end
165+ end
166+ ```
167+
168+ See full application code in [ helloworld_transcoding] ( examples/helloworld_transcoding ) example.
169+
170+ ### ** Start Application**
171+
172+ 1 . Start gRPC Server in your supervisor tree or Application module:
173+
174+ ``` elixir
66175# In the start function of your Application
67176defmodule HelloworldApp do
68177 use Application
@@ -78,7 +187,7 @@ defmodule HelloworldApp do
78187end
79188```
80189
81- 4 . Call rpc:
190+ 2 . Call rpc:
82191
83192``` elixir
84193iex> {:ok , channel} = GRPC .Stub .connect (" localhost:50051" )
@@ -90,7 +199,27 @@ iex> {:ok, channel} = GRPC.Stub.connect("localhost:50051", interceptors: [GRPC.C
90199.. .
91200```
92201
93- Check [ examples] ( examples ) and [ interop] ( interop ) (Interoperability Test) for some examples.
202+ Check the [ examples] ( examples ) and [ interop] ( interop ) directories in the project's source code for some examples.
203+
204+ ## Client Adapter and Configuration
205+
206+ The default adapter used by ` GRPC.Stub.connect/2 ` is ` GRPC.Client.Adapter.Gun ` . Another option is to use ` GRPC.Client.Adapters.Mint ` instead, like so:
207+
208+ ``` elixir
209+ GRPC .Stub .connect (" localhost:50051" ,
210+ # Use Mint adapter instead of default Gun
211+ adapter: GRPC .Client .Adapters .Mint
212+ )
213+ ```
214+
215+ The ` GRPC.Client.Adapters.Mint ` adapter accepts custom configuration. To do so, you can configure it from your mix application via:
216+
217+ ``` elixir
218+ # File: your application's config file.
219+ config :grpc , GRPC .Client .Adapters .Mint , custom_opts
220+ ```
221+
222+ The accepted options for configuration are the ones listed on [ Mint.HTTP.connect/4] ( https://hexdocs.pm/mint/Mint.HTTP.html#connect/4-options )
94223
95224## Features
96225
@@ -99,11 +228,13 @@ Check [examples](examples) and [interop](interop)(Interoperability Test) for som
99228 - [ Server-streaming] ( https://grpc.io/docs/what-is-grpc/core-concepts/#server-streaming-rpc )
100229 - [ Client-streaming] ( https://grpc.io/docs/what-is-grpc/core-concepts/#client-streaming-rpc )
101230 - [ Bidirectional-streaming] ( https://grpc.io/docs/what-is-grpc/core-concepts/#bidirectional-streaming-rpc )
231+ - [ HTTP Transcoding] ( https://cloud.google.com/endpoints/docs/grpc/transcoding )
102232- [ TLS Authentication] ( https://grpc.io/docs/guides/auth/#supported-auth-mechanisms )
103233- [ Error handling] ( https://grpc.io/docs/guides/error/ )
104- - Interceptors(See [ ` GRPC.Endpoint ` ] ( https://github.com/elixir-grpc/grpc/blob/master/lib/grpc/endpoint.ex ) )
234+ - Interceptors (See [ ` GRPC.Endpoint ` ] ( https://github.com/elixir-grpc/grpc/blob/master/lib/grpc/endpoint.ex ) )
105235- [ Connection Backoff] ( https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md )
106236- Data compression
237+ - [ gRPC Reflection] ( https://github.com/elixir-grpc/grpc-reflection )
107238
108239## Benchmark
109240
0 commit comments