View Source GRPC.Server (grpc v0.9.0)

A gRPC server which handles requests by calling user-defined functions.

You should pass a GRPC.Service in when use the module:

defmodule Greeter.Service do
  use GRPC.Service, name: "ping"

  rpc :SayHello, Request, Reply
  rpc :SayGoodbye, stream(Request), stream(Reply)
end

defmodule Greeter.Server do
  use GRPC.Server, service: Greeter.Service

  def say_hello(request, _stream) do
    Reply.new(message: "Hello")
  end

  def say_goodbye(request_enum, stream) do
    requests = Enum.map request_enum, &(&1)
    GRPC.Server.send_reply(stream, reply1)
    GRPC.Server.send_reply(stream, reply2)
  end
end

Your functions should accept a client request and a GRPC.Server.Stream. The request will be a Enumerable.t(created by Elixir's Stream) of requests if it's streaming. If a reply is streaming, you need to call send_reply/2 to send replies one by one instead of returning reply in the end.

gRPC HTTP/JSON transcoding

Transcoding can be enabled by using the option http_transcode: true:

defmodule Greeter.Service do
  use GRPC.Service, name: "ping"

  rpc :SayHello, Request, Reply
  rpc :SayGoodbye, stream(Request), stream(Reply)
end

defmodule Greeter.Server do
  use GRPC.Server, service: Greeter.Service, http_transcode: true

  def say_hello(request, _stream) do
    Reply.new(message: "Hello" <> request.name)
  end

  def say_goodbye(request_enum, stream) do
    requests = Enum.map request_enum, &(&1)
    GRPC.Server.send_reply(stream, reply1)
    GRPC.Server.send_reply(stream, reply2)
  end
end

With transcoding enabled gRPC methods can be used over HTTP/1 with JSON i.e

POST localhost/helloworld.Greeter/SayHello`
Content-Type: application/json
{
  "message": "gRPC"
}

HTTP/1.1 200 OK
Content-Type: application/json
{
  "message": "Hello gRPC"
}

By using option (google.api.http) annotations in the .proto file the mapping between HTTP/JSON to gRPC methods and parameters can be customized:

syntax = "proto3";

import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/greeter/{name}"
    };
  }
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

In addition to the POST localhost/helloworld.Greeter/SayHello route in the previous examples this creates an additional route: GET localhost/v1/greeter/:name

GET localhost/v1/greeter/gRPC
Accept: application/json

HTTP/1.1 200 OK
Content-Type: application/json
{
  "message": "Hello gRPC"
}

For more comprehensive documentation on annotation usage in .proto files see

Summary

Functions

Send custom metadata(headers).

Set compressor to compress responses. An accepted compressor will be set if clients use one, even if set_compressor is not called. But this can be called to override the chosen.

Set custom metadata(headers).

Set custom trailers, which will be sent in the end.

Types

@type rpc() :: (rpc_req(), GRPC.Server.Stream.t() -> rpc_return())
@type rpc_req() :: struct() | Enumerable.t()
@type rpc_return() :: struct() | any()

Functions

Link to this function

send_headers(stream, headers)

View Source
@spec send_headers(GRPC.Server.Stream.t(), map()) :: GRPC.Server.Stream.t()

Send custom metadata(headers).

You can send headers only once, before that you can set headers using set_headers/2.

Link to this function

send_reply(stream, reply, opts \\ [])

View Source

Send streaming reply.

Examples

iex> GRPC.Server.send_reply(stream, reply)
Link to this function

set_compressor(stream, compressor)

View Source
@spec set_compressor(GRPC.Server.Stream.t(), module()) :: GRPC.Server.Stream.t()

Set compressor to compress responses. An accepted compressor will be set if clients use one, even if set_compressor is not called. But this can be called to override the chosen.

Link to this function

set_headers(stream, headers)

View Source
@spec set_headers(GRPC.Server.Stream.t(), map()) :: GRPC.Server.Stream.t()

Set custom metadata(headers).

You can set headers more than once.

Link to this function

set_trailers(stream, trailers)

View Source
@spec set_trailers(GRPC.Server.Stream.t(), map()) :: GRPC.Server.Stream.t()

Set custom trailers, which will be sent in the end.