Skip to content

Commit 0cfb96d

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents bae8b92 + 7da75a0 commit 0cfb96d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1720
-312
lines changed

README.md

Lines changed: 100 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@
1919
- [Bidirectional Streaming](#bidirectional-streaming)
2020
- [Application Startup](#application-startup)
2121
- [Client Usage](#client-usage)
22+
- [Basic Connection and RPC](#basic-connection-and-rpc)
23+
- [Using Interceptors](#using-interceptors)
24+
- [Target Schemes and Resolvers](#target-schemes-and-resolvers)
25+
- [Supported formats](#supported-formats)
26+
- [Example (DNS)](#example-dns)
27+
- [Example (Unix socket)](#example-unix-socket)
28+
- [Compression and Metadata](#compression-and-metadata)
29+
- [Client Adapters](#client-adapters)
30+
- [Using Mint Adapter](#using-mint-adapter)
2231
- [HTTP Transcoding](#http-transcoding)
2332
- [CORS](#cors)
2433
- [Features](#features)
@@ -78,6 +87,8 @@ protoc --elixir_out=plugins=grpc:./lib -I./priv/protos helloworld.proto
7887

7988
All RPC calls must be implemented using the stream-based API, even for unary requests.
8089

90+
>__NOTE__: The old API was deprecated based on `GRPC.Server.send_reply/2` and direct `struct` returns was deprecated as of version `0.10.x`.
91+
8192
### Unary RPC using Stream API
8293

8394
```elixir
@@ -133,7 +144,10 @@ def say_bid_stream_hello(request, materializer) do
133144
|> GRPC.Stream.run_with(materializer)
134145
end
135146
```
136-
__💡__ The Stream API supports composable stream transformations via `ask`, `map`, `run` and others functions, enabling clean and declarative stream pipelines. For a complete list of available operators see [here](lib/grpc/stream.ex).
147+
148+
The Stream API supports composable stream transformations via `ask`, `map`, `run` and other functions, enabling clean and declarative stream pipelines. For a complete list of available operators and detailed documentation, see [`GRPC.Stream`](lib/grpc/stream.ex).
149+
150+
---
137151

138152
## Application Startup
139153

@@ -166,38 +180,106 @@ end
166180

167181
# Client Usage
168182

183+
This section demonstrates how to establish client connections and perform RPC calls using the Elixir gRPC client.
184+
185+
---
186+
187+
## Basic Connection and RPC
188+
169189
```elixir
170190
iex> {:ok, channel} = GRPC.Stub.connect("localhost:50051")
171191
iex> request = Helloworld.HelloRequest.new(name: "grpc-elixir")
172192
iex> {:ok, reply} = channel |> Helloworld.GreetingServer.Stub.say_unary_hello(request)
193+
```
194+
195+
---
196+
197+
## Using Interceptors
198+
199+
Client interceptors allow you to add logic to the request/response lifecycle, such as logging, tracing, or authentication.
200+
201+
```elixir
202+
iex> {:ok, channel} =
203+
...> GRPC.Stub.connect("localhost:50051",
204+
...> interceptors: [GRPC.Client.Interceptors.Logger]
205+
...> )
206+
iex> request = Helloworld.HelloRequest.new(name: "Alice")
207+
iex> {:ok, reply} = channel |> Helloworld.GreetingServer.Stub.say_unary_hello(request)
208+
```
209+
210+
---
211+
212+
## Target Schemes and Resolvers
173213

174-
# With interceptors
175-
iex> {:ok, channel} = GRPC.Stub.connect("localhost:50051", interceptors: [GRPC.Client.Interceptors.Logger])
176-
...
214+
The `connect/2` function supports URI-like targets that are resolved via the internal **gRPC** [Resolver](lib/grpc/client/resolver.ex).
215+
You can connect using `DNS`, `Unix Domain sockets`, `IPv4/IPv6`, or even `xDS-based endpoints`.
216+
217+
### Supported formats:
218+
219+
| Scheme | Example | Description |
220+
|:----------|:----------------------------|:---------------------------------------------|
221+
| `dns://` | `"dns://example.com:50051"` | Resolves via DNS `A/AAAA` records |
222+
| `ipv4:` | `"ipv4:10.0.0.5:50051"` | Connects directly to an IPv4 address |
223+
| `unix:` | `"unix:/tmp/service.sock"` | Connects via a Unix domain socket |
224+
| `xds:///` | `"xds:///my-service"` | Resolves via xDS control plane (Envoy/Istio) |
225+
| none | `"127.0.0.1:50051"` | Implicit DNS (default port `50051`) |
226+
227+
### Example (DNS):
228+
229+
```elixir
230+
iex> {:ok, channel} = GRPC.Stub.connect("dns://orders.prod.svc.cluster.local:50051")
231+
iex> request = Orders.GetOrderRequest.new(id: "123")
232+
iex> {:ok, reply} = channel |> Orders.OrderService.Stub.get_order(request)
233+
```
234+
235+
### Example (Unix socket):
236+
237+
```elixir
238+
iex> {:ok, channel} = GRPC.Stub.connect("unix:/tmp/my.sock")
239+
```
240+
241+
>__NOTE__: When using `DNS` or `xDS` targets, the connection layer periodically refreshes endpoints.
242+
---
243+
244+
## Compression and Metadata
245+
246+
You can specify message compression and attach default headers to all requests.
247+
248+
```elixir
249+
iex> {:ok, channel} =
250+
...> GRPC.Stub.connect("localhost:50051",
251+
...> compressor: GRPC.Compressor.Gzip,
252+
...> headers: [{"authorization", "Bearer my-token"}]
253+
...> )
177254
```
178255

179-
Check the [examples](examples) and [interop](interop) directories in the project's source code for some examples.
256+
---
257+
258+
## Client Adapters
180259

181-
## Client Adapter and Configuration
260+
By default, `GRPC.Stub.connect/2` uses the **Gun** adapter.
261+
You can switch to **Mint** (pure Elixir HTTP/2) or other adapters as needed.
182262

183-
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:
263+
### Using Mint Adapter
184264

185265
```elixir
186-
GRPC.Stub.connect("localhost:50051",
187-
# Use Mint adapter instead of default Gun
188-
adapter: GRPC.Client.Adapters.Mint
189-
)
266+
iex> GRPC.Stub.connect("localhost:50051",
267+
...> adapter: GRPC.Client.Adapters.Mint
268+
...> )
190269
```
191270

192-
The `GRPC.Client.Adapters.Mint` adapter accepts custom configuration. To do so, you can configure it from your mix application via:
271+
You can configure adapter options globally via your application’s config:
193272

194273
```elixir
195-
# File: your application's config file.
196-
config :grpc, GRPC.Client.Adapters.Mint, custom_opts
274+
# File: config/config.exs
275+
config :grpc, GRPC.Client.Adapters.Mint,
276+
timeout: 10_000,
277+
transport_opts: [cacertfile: "/etc/ssl/certs/ca-certificates.crt"]
197278
```
198279

199-
The accepted options for configuration are the ones listed on [Mint.HTTP.connect/4](https://hexdocs.pm/mint/Mint.HTTP.html#connect/4-options)
280+
The accepted options are the same as [`Mint.HTTP.connect/4`](https://hexdocs.pm/mint/Mint.HTTP.html#connect/4-options).
200281

282+
---
201283

202284
### **HTTP Transcoding**
203285

@@ -264,7 +346,7 @@ defmodule Helloworld.Greeter.Server do
264346
end
265347
```
266348

267-
See full application code in [helloworld_transcoding](examples/helloworld_transcoding) example.
349+
See full application code in [helloworld_transcoding](https://github.com/elixir-grpc/tree/master/examples/helloworld_transcoding) example.
268350

269351
### **CORS**
270352

@@ -300,9 +382,9 @@ end
300382

301383
## Benchmark
302384

303-
1. [Simple benchmark](examples/helloworld/README.md#Benchmark) by using [ghz](https://ghz.sh/)
385+
1. [Simple benchmark](https://github.com/elixir-grpc/tree/master/examples/helloworld/README.md#Benchmark) by using [ghz](https://ghz.sh/)
304386

305-
2. [Benchmark](benchmark) followed by official spec
387+
2. [Benchmark](https://github.com/elixir-grpc/tree/master/benchmark) followed by official spec
306388

307389
## Contributing
308390

benchmark/lib/grpc/core/stats.pb.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule Grpc.Core.Bucket do
22
@moduledoc false
33

4-
use Protobuf, protoc_gen_elixir_version: "0.14.1", syntax: :proto3
4+
use Protobuf, protoc_gen_elixir_version: "0.14.0", syntax: :proto3
55

66
field :start, 1, type: :double
77
field :count, 2, type: :uint64
@@ -10,15 +10,15 @@ end
1010
defmodule Grpc.Core.Histogram do
1111
@moduledoc false
1212

13-
use Protobuf, protoc_gen_elixir_version: "0.14.1", syntax: :proto3
13+
use Protobuf, protoc_gen_elixir_version: "0.14.0", syntax: :proto3
1414

1515
field :buckets, 1, repeated: true, type: Grpc.Core.Bucket
1616
end
1717

1818
defmodule Grpc.Core.Metric do
1919
@moduledoc false
2020

21-
use Protobuf, protoc_gen_elixir_version: "0.14.1", syntax: :proto3
21+
use Protobuf, protoc_gen_elixir_version: "0.14.0", syntax: :proto3
2222

2323
oneof :value, 0
2424

@@ -30,7 +30,7 @@ end
3030
defmodule Grpc.Core.Stats do
3131
@moduledoc false
3232

33-
use Protobuf, protoc_gen_elixir_version: "0.14.1", syntax: :proto3
33+
use Protobuf, protoc_gen_elixir_version: "0.14.0", syntax: :proto3
3434

3535
field :metrics, 1, repeated: true, type: Grpc.Core.Metric
3636
end
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,21 @@
1+
defmodule Grpc.Testing.BenchmarkService.Service do
2+
@moduledoc false
13

4+
use GRPC.Service, name: "grpc.testing.BenchmarkService", protoc_gen_elixir_version: "0.14.0"
5+
6+
rpc :UnaryCall, Grpc.Testing.SimpleRequest, Grpc.Testing.SimpleResponse
7+
8+
rpc :StreamingCall, stream(Grpc.Testing.SimpleRequest), stream(Grpc.Testing.SimpleResponse)
9+
10+
rpc :StreamingFromClient, stream(Grpc.Testing.SimpleRequest), Grpc.Testing.SimpleResponse
11+
12+
rpc :StreamingFromServer, Grpc.Testing.SimpleRequest, stream(Grpc.Testing.SimpleResponse)
13+
14+
rpc :StreamingBothWays, stream(Grpc.Testing.SimpleRequest), stream(Grpc.Testing.SimpleResponse)
15+
end
16+
17+
defmodule Grpc.Testing.BenchmarkService.Stub do
18+
@moduledoc false
19+
20+
use GRPC.Stub, service: Grpc.Testing.BenchmarkService.Service
21+
end

0 commit comments

Comments
 (0)