apigenie-generatorProtobuf and gRPCserver elixir-grpc
server elixir-grpc
Generate an Elixir gRPC server on elixir-grpc from a .proto
file and the files it imports.
Usage
apigenie-generator server elixir-grpc [...OPTIONS] INPUT_FILE
Description
The input is the .proto file declaring the services. The files it imports are looked up in the
directories of --proto-path, then next to it; google/protobuf, google/api and google/rpc
imports need no files. Only proto3 files are read.
The generator writes a Mix project (Elixir 1.18 or later) depending on grpc_server 1.0 and
protobuf 0.17. Its code passes mix format --check-formatted, mix compile --warnings-as-errors, mix credo --strict and mix dialyzer. No protoc is needed: the modules of
the messages are those protoc-gen-elixir would write.
| File | Contents |
|---|---|
lib/proto/<path>.pb.ex |
per .proto file, a module per message, map entry and enum (use Protobuf), and a <Service>.Service module per service (use GRPC.Service) |
lib/<app>/<service>.ex |
a behaviour per service, with a callback per method |
lib/<app>/<service>/server.ex |
the GRPC.Server of the service, calling the configured implementation |
lib/<app>/endpoint.ex, application.ex |
the endpoint running the servers, and the application starting it |
config/config.exs, config/runtime.exs |
the port (50051, or PORT) |
mix.exs, .formatter.exs, .gitignore, README.md |
the project |
mix deps.get
mix run --no-halt
Messages
Modules are named as protoc-gen-elixir names them: the package camelized segment by segment, then
the message (carpetexpress.v1.Shipment.Parcel is Carpetexpress.V1.Shipment.Parcel). The
(elixirpb.file).module_prefix option of a file, or the package_prefix option of the generator,
change the prefix. Fields are declared with field and the options protoc-gen-elixir writes
(repeated, proto3_optional, json_name, map, enum, oneof, packed, deprecated), oneofs
with oneof. Comments become @moduledoc and # comments.
Well-known types are the modules of the protobuf package (Google.Protobuf.Timestamp, …), the
types of google/api, google/rpc and google/type those of googleapis.
Services
A service is a behaviour, <Root>.<Service>, with a callback per method named as GRPC.Server names
it (GetShipment is get_shipment/2). Implement it and configure the implementation:
config :carpet_express, CarpetExpress.ShipmentService, impl: MyApp.ShipmentService
defmodule MyApp.ShipmentService do
@behaviour CarpetExpress.ShipmentService
@impl true
def get_shipment(request, _stream), do: MyApp.Shipments.fetch!(request.id)
@impl true
def import_shipments(requests, _stream) do
imported = requests |> Enum.map(&MyApp.Shipments.book/1) |> length()
%Carpetexpress.V1.ImportShipmentsResponse{imported: imported}
end
# ...
end
A callback receives the request, or an Enumerable of the requests of a client or bidirectional
stream, and the GRPC.Server.Stream of the call. It returns the response, or an Enumerable of
the responses of a server or bidirectional stream, which the server sends one by one. Raising
GRPC.RPCError answers with its status. Methods without an implementation answer UNIMPLEMENTED.
Limitations
extendblocks (custom options, proto2-style extensions) aren’t generated; a warning names the file.(google.api.field_behavior) = REQUIREDisn’t checked: protobuf-elixir has no required fields.- HTTP/JSON transcoding (
google.api.http) isn’t turned on.
Options
-I, –proto-path DIR
Directory searched for the imported files, like protoc’s --proto_path. Can be repeated.
-c, –config
Path to the configuration file to use. See the “Configuration” section for more information.
-o, –output
Directory where the project is generated.
–package-name
Name of the Mix application, converted to snake_case (carpet-express gives carpet_express
and the root module CarpetExpress). Defaults to the name of the output directory.
–package-version
Version of the Mix project; 0.1.0 by default.
-p, –property NAME=VALUE
Sets a generator option (see below), e.g. -p dev_deps=false. Options given on the command line
take precedence over the configuration file.
Configuration
version: '1.0'
commands:
generate:
server_elixir_grpc:
app: carpet_express
package_prefix: carpet_express.proto
| Option | Type | Default | Description |
|---|---|---|---|
app |
string | name of the output directory | Name of the Mix application (snake_case, the directory under lib/); also set by --package-name. |
namespace |
string | the application in PascalCase | Root module of the modules of the application (behaviours, servers, endpoint), e.g. CarpetExpress. |
package_prefix |
string | Prepended to the package in the names of the modules of messages, enums and services, like protoc-gen-elixir’s package_prefix. |
|
dev_deps |
boolean | true |
Lists credo and dialyxir as dependencies of mix.exs (only: :dev). |