# `GRPC.Server`
[🔗](https://github.com/elixir-grpc/grpc_server/blob/v1.0.1/lib/grpc/server.ex#L1)

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"
    }

Custom codecs do not work with HTTP/JSON transcoding.
For more comprehensive documentation on annotation usage in `.proto` files [see](https://cloud.google.com/endpoints/docs/grpc/transcoding)

# `rpc`

```elixir
@type rpc() :: (rpc_req(), GRPC.Server.Stream.t() -&gt; rpc_return())
```

# `rpc_req`

```elixir
@type rpc_req() :: struct() | Enumerable.t()
```

# `rpc_return`

```elixir
@type rpc_return() :: struct() | any()
```

# `send_headers`

```elixir
@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`.

# `send_reply`

Send streaming reply.

## Examples

    iex> GRPC.Server.send_reply(stream, reply)

# `set_compressor`

```elixir
@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.

# `set_headers`

```elixir
@spec set_headers(GRPC.Server.Stream.t(), map()) :: GRPC.Server.Stream.t()
```

Set custom metadata(headers).

You can set headers more than once.

# `set_trailers`

```elixir
@spec set_trailers(GRPC.Server.Stream.t(), map()) :: GRPC.Server.Stream.t()
```

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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
