{"id":2128,"date":"2022-07-22T06:56:53","date_gmt":"2022-07-22T13:56:53","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sdk\/?p=2128"},"modified":"2022-07-22T07:25:44","modified_gmt":"2022-07-22T14:25:44","slug":"announcing-the-stable-release-of-the-azure-service-bus-client-library-for-go","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sdk\/announcing-the-stable-release-of-the-azure-service-bus-client-library-for-go\/","title":{"rendered":"Announcing the stable release of the Azure Service Bus client library for Go"},"content":{"rendered":"<p>We&#8217;re excited to announce the stable release of the <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/tree\/main\/sdk\/messaging\/azservicebus\">Azure Service Bus client library for Go<\/a>. <a href=\"https:\/\/azure.microsoft.com\/services\/service-bus\/\">Azure Service Bus<\/a> is an enterprise cloud messaging service, enabling the building of scalable cloud solutions.<\/p>\n<blockquote><p>NOTE: If you&#8217;re using the previous Azure Service Bus library for Go and would like to upgrade, we&#8217;ve put together a <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/blob\/main\/sdk\/messaging\/azservicebus\/migrationguide.md\">migration guide<\/a> that you can use to port your application over.<\/p><\/blockquote>\n<h2>Install the package<\/h2>\n<p>The Azure Service Bus library can be installed using <code>go get<\/code>:<\/p>\n<pre><code class=\"language-bash\">go get github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\r\n\r\n# Optionally, if you also want to use Azure Identity for authentication\r\ngo get github.com\/Azure\/azure-sdk-for-go\/sdk\/azidentity<\/code><\/pre>\n<p>This blog post assumes you have a working development environment for Go 1.18 or above, and that you have an Azure Service Bus namespace.<\/p>\n<p>For instructions on creating an Azure Service Bus namespace, follow this <a href=\"https:\/\/docs.microsoft.com\/azure\/service-bus-messaging\/service-bus-create-namespace-portal\">step-by-step guide<\/a>.<\/p>\n<h2>Creating the <code>Client<\/code><\/h2>\n<p>The Service Bus <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\/#Client\"><code>Client<\/code><\/a> is used to create <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\/#Sender\"><code>Senders<\/code><\/a> and <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\/#Receiver\"><code>Receivers<\/code><\/a>. <code>Senders<\/code> and <code>Receivers<\/code> allow you to send messages to Queues and Topics and receive messages from Queues and Subscriptions, respectively.<\/p>\n<p>You can create a <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\/#Client\"><code>Client<\/code><\/a> using a Service Bus connection string (obtained via the <a href=\"https:\/\/portal.azure.com\/\">Azure portal<\/a>) or with a <code>TokenCredential<\/code> (for example, <code>DefaultAzureCredential<\/code>) from the <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/tree\/main\/sdk\/azidentity\">Azure Identity library<\/a>.<\/p>\n<h2>Using the <code>DefaultAzureCredential<\/code> token credential<\/h2>\n<p>The <code>DefaultAzureCredential<\/code> combines several credential types into one easy-to-use type. It can authenticate using the Azure CLI, managed identities, and more. For more information, see the <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/tree\/main\/sdk\/azidentity#defaultazurecredential\">azidentity documentation<\/a>.<\/p>\n<pre><code class=\"language-go\">import (\r\n    \"github.com\/Azure\/azure-sdk-for-go\/sdk\/azidentity\"\r\n    \"github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\"\r\n)\r\n\r\nfunc main() {\r\n    \/\/ For more information about the DefaultAzureCredential:\r\n    \/\/ https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/azidentity#NewDefaultAzureCredential\r\n    tokenCredential, err := azidentity.NewDefaultAzureCredential(nil)\r\n\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n\r\n    client, err := azservicebus.NewClient(\"&lt;ex: my-service-bus.servicebus.windows.net&gt;\", tokenCredential, nil)\r\n\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n\r\n    defer client.Close(context.TODO())\r\n}<\/code><\/pre>\n<h2>Using a Service Bus connection string<\/h2>\n<p>Azure Service Bus also supports authentication using a connection string, which you can get from the portal. Connection strings can be scoped to the namespace\nor to individual queues or topics.<\/p>\n<p>For instructions on getting a connection string, see the documentation here: <a href=\"https:\/\/docs.microsoft.com\/azure\/service-bus-messaging\/service-bus-quickstart-portal#get-the-connection-string\">link<\/a>.<\/p>\n<pre><code class=\"language-go\">import (\r\n    \"github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\"\r\n)\r\n\r\nfunc main() {\r\n    client, err := azservicebus.NewClientFromConnectionString(\"&lt;Service Bus connection string&gt;\", nil)\r\n\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n\r\n    defer client.Close(context.TODO())\r\n}<\/code><\/pre>\n<h2>Sending messages<\/h2>\n<p>Using a <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\/#Sender\"><code>Sender<\/code><\/a>, you can send <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\/#Message\"><code>Messages<\/code><\/a>.<\/p>\n<p><code>Message<\/code> can be used to send any data that can be converted into a slice of bytes using the <code>Body<\/code> field. It also contains fields like <code>Subject<\/code> or <code>ApplicationProperties<\/code>, which can be used to add metadata to the message.<\/p>\n<pre><code class=\"language-go\">package main\r\n\r\nimport (\r\n    \"context\"\r\n\r\n    \"github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\"\r\n)\r\n\r\nfunc main() {\r\n    \/\/ NOTE: See the \"Using the `DefaultAzureCredential`\" section above to use an Azure\r\n    \/\/ Identity credential instead of a connection string.\r\n    client, err := azservicebus.NewClientFromConnectionString(\"&lt;Service Bus connection string&gt;\", nil)\r\n\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n\r\n    defer client.Close(context.TODO())\r\n\r\n    sender, err := client.NewSender(\"&lt;queue or topic&gt;\", nil)\r\n\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n\r\n    defer sender.Close(context.TODO())\r\n\r\n    subject := \"greetings\"\r\n\r\n    \/\/ send a single message\r\n    err = sender.SendMessage(context.TODO(), &amp;azservicebus.Message{\r\n        Body:    []byte(\"hello world!\"),\r\n        Subject: &amp;subject,\r\n        ApplicationProperties: map[string]interface{}{\r\n            \"GreetingType\": \"jovial\",\r\n        },\r\n    })\r\n\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n}<\/code><\/pre>\n<p>For improved efficiency, you can also send multiple messages in a single batch:<\/p>\n<pre><code class=\"language-go\">package main\r\n\r\nimport (\r\n    \"context\"\r\n    \"errors\"\r\n    \"fmt\"\r\n\r\n    \"github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\"\r\n)\r\n\r\nfunc main() {\r\n    \/\/ NOTE: See the \"Using the `DefaultAzureCredential`\" section above to use an Azure\r\n    \/\/ Identity credential instead of a connection string.\r\n    client, err := azservicebus.NewClientFromConnectionString(\"&lt;Service Bus connection string&gt;\", nil)\r\n\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n\r\n    defer client.Close(context.TODO())\r\n\r\n    sender, err := client.NewSender(\"&lt;queue or topic&gt;\", nil)\r\n\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n\r\n    defer sender.Close(context.TODO())\r\n\r\n    \/\/ or send multiple messages in a single batch\r\n    batch, err := sender.NewMessageBatch(context.TODO(), nil)\r\n\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n\r\n    messagesToAdd := []*azservicebus.Message{\r\n        {\r\n            Body: []byte(\"hello world\"),\r\n            ApplicationProperties: map[string]interface{}{\r\n                \"GreetingType\": \"jovial\",\r\n            },\r\n        },\r\n        {\r\n            Body: []byte(\"hello, again\"),\r\n            ApplicationProperties: map[string]interface{}{\r\n                \"GreetingType\": \"jovial\",\r\n            },\r\n        },\r\n    }\r\n\r\n    fmt.Printf(\"Adding messages to batches...\\n\")\r\n\r\n    var batchesToSend []*azservicebus.MessageBatch\r\n\r\n    for i := 0; i &lt; len(messagesToAdd); i++ {\r\n        err := batch.AddMessage(messagesToAdd[i], nil)\r\n\r\n        if errors.Is(err, azservicebus.ErrMessageTooLarge) {\r\n            if batch.NumMessages() == 0 {\r\n                fmt.Printf(\"Message is too large to fit into a batch. Will need to be resized\/split.\\n\")\r\n                panic(err)\r\n            }\r\n\r\n            fmt.Printf(\"Current batch is full, contains %d bytes, %d message(s)\\n\", batch.NumBytes(), batch.NumMessages())\r\n            batchesToSend = append(batchesToSend, batch)\r\n\r\n            newBatch, err := sender.NewMessageBatch(context.TODO(), nil)\r\n\r\n            if err != nil {\r\n                panic(err)\r\n            }\r\n\r\n            fmt.Printf(\"New batch created, resuming adding messages\\n\")\r\n            batch = newBatch\r\n\r\n            \/\/ retry adding this message to the batch.\r\n            i--\r\n        } else if err != nil {\r\n            panic(err)\r\n        }\r\n    }\r\n\r\n    if batch.NumMessages() &gt; 0 {\r\n        fmt.Printf(\"Adding final batch, contains %d bytes, %d message(s)\\n\", batch.NumBytes(), batch.NumMessages())\r\n        batchesToSend = append(batchesToSend, batch)\r\n    }\r\n\r\n    for _, batch := range batchesToSend {\r\n        fmt.Printf(\"Sending batch #%d...\\n\", i)\r\n        if err := sender.SendMessageBatch(context.TODO(), batch, nil); err != nil {\r\n            panic(err)\r\n        }\r\n    }\r\n}<\/code><\/pre>\n<h2>Receiving messages using the <code>Receiver<\/code><\/h2>\n<p>The <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\/#Receiver\">Receiver<\/a>:<\/p>\n<pre><code class=\"language-go\">package main\r\n\r\nimport (\r\n    \"context\"\r\n    \"errors\"\r\n    \"fmt\"\r\n    \"sync\"\r\n\r\n    \"github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\"\r\n)\r\n\r\nfunc main() {\r\n    \/\/ NOTE: See the \"Using the `DefaultAzureCredential`\" section above to use an Azure\r\n    \/\/ Identity credential instead of a connection string.\r\n    client, err := azservicebus.NewClientFromConnectionString(\"&lt;Service Bus connection string&gt;\", nil)\r\n\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n\r\n    defer client.Close(context.TODO())\r\n\r\n    receiver, err := client.NewReceiverForQueue(\r\n        \"&lt;queue&gt;\",\r\n        nil)\r\n    \/\/ or, if you want to connect to a subscription for a topic:\r\n    \/\/ client.NewReceiverForSubscription(\"&lt;topic&gt;\", \"&lt;subscription&gt;\", nil)\r\n\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n\r\n    defer receiver.Close(context.TODO())\r\n\r\n    \/\/ this loop will receive up to 10 messages each iteration and\r\n    \/\/ process and complete them in parallel.\r\n    for {\r\n        messages, err := receiver.ReceiveMessages(context.TODO(), 10, nil)\r\n\r\n        if err != nil {\r\n            panic(err)\r\n        }\r\n\r\n        wg := sync.WaitGroup{}\r\n\r\n        for _, message := range messages {\r\n            wg.Add(1)\r\n\r\n            go func(m *azservicebus.ReceivedMessage) {\r\n                defer wg.Done()\r\n\r\n                \/\/ use the message\r\n\r\n                greetingType, ok := m.ApplicationProperties[\"GreetingType\"].(string)\r\n\r\n                if !ok {\r\n                    \/\/ property isn't a string, or wasn't in the map\r\n                    panic(errors.New(\"GreetingType application property wasn't present or wasn't a string\"))\r\n                }\r\n\r\n                \/\/ The .Body of the message is just bytes - for our example we'll just assume\r\n                \/\/ it's the bytes of a string.\r\n                fmt.Printf(\"Message received with contents '%s', greeting type '%s'\\n\", string(m.Body), greetingType)\r\n\r\n                \/\/ For more information about settling messages:\r\n                \/\/ https:\/\/docs.microsoft.com\/azure\/service-bus-messaging\/message-transfers-locks-settlement#settling-receive-operations\r\n                if err := receiver.CompleteMessage(context.TODO(), m, nil); err != nil {\r\n                    panic(err)\r\n                }\r\n            }(message)\r\n        }\r\n\r\n        wg.Wait()\r\n    }\r\n}<\/code><\/pre>\n<p>For more information about the Receiver, see the <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus#Receiver\">API documentation<\/a> and <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus#pkg-examples\">examples<\/a>.<\/p>\n<h2>Summary<\/h2>\n<p>We hope this post offered some insight into the Azure Service Bus package. We welcome any feedback or suggestions at the <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/issues\">azure-sdk-for-go<\/a> GitHub repository.<\/p>\n<p>We have more examples than what we&#8217;ve highlighted here in the blog post. You can view them through pkg.go.dev (<a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus#pkg-examples\">link<\/a>) or in GitHub (<a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/tree\/main\/sdk\/messaging\/azservicebus\">link<\/a>).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;re excited to announce the stable release of the Azure Service Bus client library for Go. Azure Service Bus is an enterprise cloud messaging service, enabling the building of scalable cloud solutions. NOTE: If you&#8217;re using the previous Azure Service Bus library for Go and would like to upgrade, we&#8217;ve put together a migration guide [&hellip;]<\/p>\n","protected":false},"author":45459,"featured_media":2134,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[853,810,811,798],"class_list":["post-2128","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sdk","tag-client-libraries","tag-go","tag-golang","tag-servicebus"],"acf":[],"blog_post_summary":"<p>We&#8217;re excited to announce the stable release of the Azure Service Bus client library for Go. Azure Service Bus is an enterprise cloud messaging service, enabling the building of scalable cloud solutions. NOTE: If you&#8217;re using the previous Azure Service Bus library for Go and would like to upgrade, we&#8217;ve put together a migration guide [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/2128","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/users\/45459"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/comments?post=2128"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/2128\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media\/2134"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media?parent=2128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/categories?post=2128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/tags?post=2128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}