google_pubsub_grpc

API wrapper around Google Pub Sub gRPC protocol. Code in lib/google/pubsub/v1/pubsub.pb.ex is generated using the protoc utility. Check protobuf-elixir package for more details, if interested.

The only thing this package adds to the auto-generated client code is a few helper methods.

Installation

Add the following to your mix.exs:

def deps do
  [
    {:goth, "~> 1.2.0"},
    {:cowlib, "~> 2.9.0", override: true},
    {:google_protos, "~> 0.1.0"},
    {:google_pubsub_grpc, "~> 0.2.0-beta.1"}
  ]
end

Configuration

Set the environment variable GOOGLE_APPLICATION_CREDENTIALS to point to a gcloud credentials file.

The goth package shows more ways to configure access, e.g.:

config :goth, json: File.read!(System.get_env("GOOGLE_APPLICATION_CREDENTIALS"))

After configuration, Google project id is available by calling helper functions Google.Pubsub.GRPC.project_id() or Google.Pubsub.GRPC.full_project_id() (with "projects/" prepended to it.

Emulator Support

Method Google.Pubsub.GRPC.channel checks environment variable PUBSUB_EMULATOR_HOST and if present (e.g. localhost:8787) uses its value as the server endpoint.

{:ok, channel} = Google.Pubsub.GRPC.channel()

To define Google project id for the emulator use goth configuration like so:

config :goth, json: nil, project_id: "emulator-project-id"

API Usage

Note that project id, topic and subscription names are passed to the grpc client in their "full" form, e.g. "projects/my-project/topics/my-topic". There are a couple of helper functions in the Google.Api.PubSub.GRPC module to convert between the full form and its shorter variant, e.g. "my-topic".

To get a channel (connection to server):

{:ok, channel} = Google.Pubsub.GRPC.channel()

Additional options are interceptors and accepted_compressors:

{:ok, channel} = Google.Pubsub.GRPC.channel(interceptors: [GRPC.Logger.Client])
{:ok, channel} = Google.Pubsub.GRPC.channel(interceptors: [{GRPC.Logger.Client, level: :info}]
{:ok, channel} = Google.Pubsub.GRPC.channel(accepted_compressors: [GRPC.Compressor.Gzip])

To get the list of topics:

request =
  Google.Pubsub.V1.ListTopicsRequest.new(project: Google.Pubsub.GRPC.full_project_id())

{:ok, response} = channel |> Google.Pubsub.V1.Publisher.Stub.list_topics(request)

To get topic's details:

request =
  Google.Pubsub.V1.GetTopicRequest.new(
    topic: Google.Pubsub.GRPC.full_topic_name("my-topic")
  )

{:ok, response} = channel |> Google.Pubsub.V1.Publisher.Stub.get_topic(request)

To create a new topic:

{:ok, topic} =
  channel
  |> Google.Pubsub.V1.Publisher.Stub.create_topic(%Google.Pubsub.V1.Topic{
    name: Google.Pubsub.GRPC.full_topic_name("my-topic")
  })

To delete a topic:

{:ok, _} =
  channel
  |> Google.Pubsub.V1.Publisher.Stub.delete_topic(%Google.Pubsub.V1.Topic{
    name: Google.Pubsub.GRPC.full_topic_name("my-topic")
  })

To create a new subscription on a topic:

{:ok, subscription} =
  channel
  |> Google.Pubsub.V1.Subscriber.Stub.create_subscription(%Google.Pubsub.V1.Subscription{
    topic: Google.Pubsub.GRPC.full_topic_name("my-topic"),
    name: Google.Pubsub.GRPC.full_subscription_name("my-subscription")
  })

To delete a subscription:

request = %Google.Pubsub.V1.DeleteSubscriptionRequest{
  subscription: Google.Pubsub.GRPC.full_subscription_name("my-subscription")
}
{:ok, _} = channel |> Google.Pubsub.V1.Subscriber.Stub.delete_subscription(request)

To publish a message on a topic:

message = %Google.Pubsub.V1.PubsubMessage{data: "string"}

request = %Google.Pubsub.V1.PublishRequest{
  topic: Google.Pubsub.GRPC.full_topic_name("my-topic"),
  messages: [message]
}

{:ok, response} = channel |> Google.Pubsub.V1.Publisher.Stub.publish(request)

To pull messages from a subscription:

request = %Google.Pubsub.V1.PullRequest{
  subscription: Google.Pubsub.GRPC.full_subscription_name("my-subscription"),
  max_messages: 10
}
{:ok, response} = channel |> Google.Pubsub.V1.Subscriber.Stub.pull(request)

To acknowledge received messages:

request = %Google.Pubsub.V1.AcknowledgeRequest{
  subscription: Google.Pubsub.GRPC.full_subscription_name("my-subscription"),
  ack_ids: Enum.map(messages, fn m -> m.ack_id end)
}
{:ok, response} = channel |> Google.Pubsub.V1.Subscriber.Stub.acknowledge(request)
'``