Current section
Files
Jump to
Current section
Files
priv/templates/service.ex.eex
# Generated by the protobuf compile. DO NOT EDIT!
defmodule <%= mod_name %>Service do
@moduledoc false
use Twirp.Service
package "<%= package %>"
service "<%= service_name %>"
<%= Enum.map methods, fn(method) -> %>
rpc :<%= method.name %>, <%= method.input %>, <%= method.output %>, :<%= method.handler_fn %>
<% end %>
end
defmodule <%= mod_name %>Client do
@moduledoc """
Generated Twirp Client
"""
@package "<%= package %>"
@service "<%= service_name %>"
@type ctx :: map()
def child_spec(opts) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [opts]}
}
end
@doc """
Starts a new service client.
## Options
* `:url` - The root url for the service.
* `:content_type` - Either `:proto` or `:json` based on the desired client type. Defaults to `:proto`.
* `:pool_config` - Configuration for the underlying Finch, http pool.
"""
def start_link(opts) do
url = opts[:url] || raise ArgumentError, "#{__MODULE__} requires a `:url` option"
content_type = opts[:content_type] || :proto
full_path = Path.join([url, "twirp", "#{@package}.#{@service}"])
pool = opts[:pool_config] || [size: 10, count: 1]
pool_config = %{
default: pool
}
:persistent_term.put({__MODULE__, :url}, full_path)
:persistent_term.put({__MODULE__, :content_type}, content_type)
Twirp.Client.HTTP.start_link(name: __MODULE__, pools: pool_config)
end
<%= Enum.map methods, fn method -> %>
<%= if method.comments != "" do %>
@doc """
<%= method.comments %>
"""<% end %>
@spec <%= method.handler_fn %>(ctx(), <%= method.input %>.t()) :: {:ok, <%= method.output %>.t()} | {:error, Twirp.Error.t()}
def <%= method.handler_fn %>(ctx \\ %{}, %<%= method.input %>{}=req) do
rpc(:<%= method.name %>, ctx, req, <%= method.input %>, <%= method.output %>)
end
<% end %>
defp rpc(method, ctx, req, input_type, output_type) do
service_url = :persistent_term.get({__MODULE__, :url})
content_type = Twirp.Encoder.type(:persistent_term.get({__MODULE__, :content_type}))
content_header = {"Content-Type", content_type}
ctx =
ctx
|> Map.put(:content_type, content_type)
|> Map.update(:headers, [content_header], & [content_header | &1])
|> Map.put_new(:deadline, 1_000)
rpcdef = %{
service_url: service_url,
method: method,
req: req,
input_type: input_type,
output_type: output_type
}
metadata = %{
client: __MODULE__,
method: method,
service: service_url
}
start = Twirp.Telemetry.start(:rpc, metadata)
case Twirp.Client.HTTP.call(__MODULE__, ctx, rpcdef) do
{:ok, resp} ->
Twirp.Telemetry.stop(:rpc, start, metadata)
{:ok, resp}
{:error, error} ->
metadata = Map.put(metadata, :error, error)
Twirp.Telemetry.stop(:rpc, start, metadata)
{:error, error}
end
end
end