1
1
# gRPC Elixir
2
2
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 )
3
4
[ ![ 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/ )
6
6
[ ![ 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 )
8
7
[ ![ 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 )
9
9
10
10
An Elixir implementation of [ gRPC] ( http://www.grpc.io/ ) .
11
11
12
12
## Table of contents
13
13
14
14
- [ Installation] ( #installation )
15
15
- [ Usage] ( #usage )
16
+ - [ Simple RPC] ( #simple-rpc )
17
+ - [ HTTP Transcoding] ( #http-transcoding )
18
+ - [ Start Application] ( #start-application )
16
19
- [ Features] ( #features )
17
20
- [ Benchmark] ( #benchmark )
18
21
- [ Contributing] ( #contributing )
@@ -24,20 +27,49 @@ The package can be installed as:
24
27
``` elixir
25
28
def deps do
26
29
[
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" }
32
31
]
33
32
end
34
33
```
35
34
36
35
## Usage
37
36
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;
39
43
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.
41
73
42
74
``` elixir
43
75
defmodule Helloworld .Greeter .Server do
@@ -50,9 +82,7 @@ defmodule Helloworld.Greeter.Server do
50
82
end
51
83
```
52
84
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
56
86
57
87
``` elixir
58
88
# Define your endpoint
@@ -62,7 +92,86 @@ defmodule Helloworld.Endpoint do
62
92
intercept GRPC .Server .Interceptors .Logger
63
93
run Helloworld .Greeter .Server
64
94
end
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;
65
110
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
66
175
# In the start function of your Application
67
176
defmodule HelloworldApp do
68
177
use Application
@@ -78,7 +187,7 @@ defmodule HelloworldApp do
78
187
end
79
188
```
80
189
81
- 4 . Call rpc:
190
+ 2 . Call rpc:
82
191
83
192
``` elixir
84
193
iex> {:ok , channel} = GRPC .Stub .connect (" localhost:50051" )
@@ -90,7 +199,27 @@ iex> {:ok, channel} = GRPC.Stub.connect("localhost:50051", interceptors: [GRPC.C
90
199
.. .
91
200
```
92
201
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 )
94
223
95
224
## Features
96
225
@@ -99,11 +228,13 @@ Check [examples](examples) and [interop](interop)(Interoperability Test) for som
99
228
- [ Server-streaming] ( https://grpc.io/docs/what-is-grpc/core-concepts/#server-streaming-rpc )
100
229
- [ Client-streaming] ( https://grpc.io/docs/what-is-grpc/core-concepts/#client-streaming-rpc )
101
230
- [ 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 )
102
232
- [ TLS Authentication] ( https://grpc.io/docs/guides/auth/#supported-auth-mechanisms )
103
233
- [ 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 ) )
105
235
- [ Connection Backoff] ( https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md )
106
236
- Data compression
237
+ - [ gRPC Reflection] ( https://github.com/elixir-grpc/grpc-reflection )
107
238
108
239
## Benchmark
109
240
0 commit comments