{"id":2038,"date":"2022-05-20T13:11:27","date_gmt":"2022-05-20T20:11:27","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sdk\/?p=2038"},"modified":"2022-05-25T16:24:32","modified_gmt":"2022-05-25T23:24:32","slug":"announcing-the-stable-release-of-the-azure-sdk-for-go","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sdk\/announcing-the-stable-release-of-the-azure-sdk-for-go\/","title":{"rendered":"Announcing the stable release of the Azure SDK for Go"},"content":{"rendered":"<p>The Azure SDK for Go team at Microsoft is excited to announce the first wave of stable Azure SDK for Go client libraries. We&#8217;re releasing client libraries for Resource Management, Azure Tables, and Service Bus. The release includes <code>azcore<\/code> and <code>azidentity<\/code> modules that form the core infrastructure for client libraries. These two modules and <a href=\"https:\/\/github.com\/Azure\/autorest.go\">autorest.go<\/a> form the building blocks for future releases of Go client libraries.<\/p>\n<h2>The journey to a stable release<\/h2>\n<p>The Azure SDK for Go was incubated in the Go language team at Microsoft. The team grew along with the Go SDK journey and we&#8217;ve reached an important milestone today. During this journey, we focused on producing idiomatic, consistent, and diagnosable libraries for the Go community, empowering Go developers to interact with Azure.\nThe packages evolved over time as we reacted to changes in the Go ecosystem and improved guidelines. We waited for key features such as Go&#8217;s generics and we addressed customer feedback to improve developer experience. We took the time to perfect the first version of Azure SDK for Go and hope you&#8217;ll love it as much as we do!<\/p>\n<p>We want to thank everyone who helped us along this journey. Your feedback made this release possible and inspired us to design a better SDK. At Azure, we&#8217;re excited and committed to bring more languages to the Azure developer platform.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>We&#8217;ll continue to expand the feature set in <code>azcore<\/code>, add more credential types to <code>azidentity<\/code>, add service packages, and expand upon Resource Manager packages. Client libraries for Key Vault, Cosmos DB, Storage, and App Configuration services are currently in beta. We hope to release stable versions in the coming months.<\/p>\n<h2>Get started<\/h2>\n<p>We have set up an entire section of content named <a href=\"https:\/\/docs.microsoft.com\/azure\/developer\/go\/\">Azure for Go developers<\/a>. The content can help you to get started and learn core concepts of the Azure SDK for Go.<\/p>\n<p>You can get the latest Azure SDK for Go libraries from <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\">pkg.go.dev<\/a> or view the source code in the <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\">Azure SDK for Go<\/a> repository on GitHub. A list of all Go modules with the latest versions is available on the <a href=\"https:\/\/azure.github.io\/azure-sdk\/releases\/latest\/all\/go.html\">Azure SDK Releases<\/a> page. The Azure SDK for Go requires version 1.18 of Go, as it utilizes Go generics.<\/p>\n<h2>Common patterns<\/h2>\n<p>The SDK follows certain idiomatic patterns throughout its libraries. Some of those patterns are described in the following sections.<\/p>\n<h3>Credentials and Identity<\/h3>\n<p>The Azure Identity module, <code>azidentity<\/code>, provides Azure Active Directory (Azure AD) token authentication support across the Go SDK. You can import the module using its package name <code>\"github.com\/Azure\/azure-sdk-for-go\/sdk\/azidentity\"<\/code>. After you&#8217;ve imported the <code>azidentity<\/code> module, you can use it to create a new credential to use throughout the lifecycle of your program. This module performs the authentication, obtains\/renews an authentication token, and adds the token to network calls automatically. <code>DefaultAzureCredential<\/code> is the easiest way to start. This convenience credential type can read credentials from your environment. Alternatively, you can visit the <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/azidentity#section-readme\">Azure Identity | pkg.go.dev<\/a> page for more credential types.<\/p>\n<pre><code class=\"language-go\">cred, err := azidentity.NewDefaultAzureCredential(nil)\r\nif err != nil {\r\n  \/\/ handle error\r\n}\r\n\r\n\/\/ use cred for creating the client<\/code><\/pre>\n<h3>Client<\/h3>\n<p>A client struct is the basic unit that lets you perform operations on a service. Depending on the library you choose, the client lets you perform service specific operations. For example, creating an Azure resource if you&#8217;re using a Resource Manager library or sending a message if you&#8217;re using the Service Bus library. Import the library using the package name <code>\"github.com\/Azure\/azure-sdk-for-go\/sdk\/&lt;foo-library-group&gt;\/&lt;foo&gt;\"<\/code>. For example, the package name for the Service Bus client library is <code>\"github.com\/Azure\/azure-sdk-for-go\/sdk\/messaging\/azservicebus\"<\/code>. You can choose to create the client using Azure AD credential.<\/p>\n<pre><code class=\"language-go\">serviceClient, err := foo.NewClient(&lt;foo-identifier&gt;, cred, &lt;ClientOption-Struct&gt;)\r\n\/\/ ClientOption struct is used to define network call properties like retry etc. \r\n\/\/ If you want default behavior pass nil, e.g. foo.NewClient(&lt;foo-identifier&gt;, cred, nil)<\/code><\/pre>\n<p>Some of our services provide alternative methods of authentication, like connection strings or shared keys:<\/p>\n<pre><code class=\"language-go\">\/\/Connection String\r\nserviceClient, err := foo.NewClientFromConnectionString(connectionString, &lt;ClientOption-Struct&gt;)\r\nif err != nil {\r\n    panic(err)\r\n}<\/code><\/pre>\n<pre><code class=\"language-go\">cred, err := foo.NewSharedKeyCredential(\"&lt;myAccountName&gt;\", \"&lt;myAccountKey&gt;\")\r\nif err != nil {\r\n    panic(err)\r\n}\r\nserviceClient, err := foo.NewClientWithSharedKey(&lt;foo-identifier&gt;, cred, &lt;ClientOption-Struct&gt;)\r\nif err != nil {\r\n    panic(err)\r\n}<\/code><\/pre>\n<p>Once you&#8217;ve created a client, you can use it to perform desired operations on the service. For example, you can use the <code>aztables<\/code> library to create a table:<\/p>\n<pre><code class=\"language-go\">_, err := serviceClient.CreateTable(context.TODO(), \"TableName\", nil)\r\nif err != nil {\r\n    panic(err)\r\n}<\/code><\/pre>\n<p>For more information on library-specific operations, see <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/\">pkg.go.dev<\/a>.<\/p>\n<h3>Pagers<\/h3>\n<p>Many Azure services return collections of items. Because the number of items can be large, the library methods return a new generic pager type <code>runtime.Pager[T]<\/code>. <code>[T]<\/code> denotes any type. This <code>Pager<\/code> allows your program to process one page of results at a time. You can use <code>pager.More<\/code> to determine if there are more result pages. Then use <code>pager.NextPage<\/code> to fetch the next result page. In this example, the <code>Foo<\/code> service returns a list of values.<\/p>\n<pre><code class=\"language-go\">serviceClient, err := foo.NewClient(&lt;foo-identifier&gt;, cred, nil)\r\nctx := context.TODO()\r\n...\r\n\r\npager := serviceClient.NewListPager(&lt;foo-specific-arguments&gt;)\r\nfor pager.More() {\r\n    nextResult, err := pager.NextPage(ctx)\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n    for _, v := range nextResult.Value {\r\n        \/\/ do something with the value\r\n        _ = v\r\n    }\r\n}<\/code><\/pre>\n<h3>Long-running operations<\/h3>\n<p>Some operations on Azure can take a long time to complete\u2014anywhere from a few seconds to a few days. Examples of such operations include copying data from a source URL to a storage blob or training an AI model to recognize forms. These long-running operations (LROs) don&#8217;t lend well to the standard HTTP flow of a relatively quick request and response.\nBy convention, methods that start an LRO are prefixed with &#8220;Begin&#8221; and return a new generic poller type <code>runtime.Poller[T]<\/code>. The Poller is used to periodically poll the service until the operation finishes. You can use <code>poller.PollUntilDone<\/code> for synchronous behavior. <code>PollUntilDone<\/code> polls at a set interval until your task is finished. Alternatively, you can use <code>poller.Poll<\/code>, <code>poller.Done<\/code>, and <code>poller.Result<\/code> to implement your own logic.<\/p>\n<pre><code class=\"language-go\">serviceClient, err := foo.NewClient(&lt;foo-identifier&gt;, cred, nil)\r\nctx := context.TODO()\r\n...\r\n\r\npoller, err := client.BeginFooOperation(ctx, &lt;foo-specific-arguments&gt;)\r\nif err != nil {\r\n    panic(err)\r\n}\r\nres, err := poller.PollUntilDone(ctx, &lt;PollUntilDoneOptions-struct&gt;)\r\nif err != nil {\r\n    panic(err)\r\n}\r\n\/\/ PollUntilDoneOptions struct is used to define polling frequency, defaults to 30s\r\n\/\/ If you want default behavior pass nil, e.g. poller.PollUntilDone(ctx, nil)<\/code><\/pre>\n<h3>Logging<\/h3>\n<p><code>azcore<\/code> module has an implementation of classification-based logging. To enable console logging for all SDK modules, set the environment variable <code>AZURE_SDK_GO_LOGGING<\/code> to <code>all<\/code>.\nAlternatively, use the <code>azcore\/log<\/code> module to control log event output or to enable logs for specific events.<\/p>\n<pre><code class=\"language-go\">import (\r\n  \"fmt\"\r\n  azlog \"github.com\/Azure\/azure-sdk-for-go\/sdk\/azcore\/log\"\r\n)\r\n\r\n\/\/ print log output to stdout\r\nazlog.SetListener(func(event azlog.Event, s string) {\r\n    fmt.Printf(\"[%s] %sn\", event, s)\r\n    \/\/ or create your own format\r\n})\r\n\r\n\/\/ pick the set of events to log\r\nazlog.SetEvents(\r\n  foo.&lt;EventConstant&gt;,\r\n  \/\/ EventConstant is a constant defined in the library check the library reference of available events\r\n  foo.&lt;EventConstant&gt;,\r\n)<\/code><\/pre>\n<h2>Feedback<\/h2>\n<p>We would love to hear about your experiences using Azure SDK for Go. Send us your feedback on our <a href=\"https:\/\/gophers.slack.com\/archives\/CA7HK8EEP\">Slack Channel<\/a> or at the <a href=\"https:\/\/discordapp.com\/channels\/723347736853741589\/933781546815606885\">#golang-friends<\/a> channel on Microsoft Open Source Discord Server.<\/p>\n<p>For feature requests, bug reports, or general support, <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/issues\/new\/choose\">open an issue<\/a> in the Azure SDK for Go repository on GitHub. For more information on how we triage issues, see the <a href=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/github-issue-support-process\/\">Azure SDK GitHub Issue Support Process<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post announces the stable release of the Azure SDK for Go.<\/p>\n","protected":false},"author":91679,"featured_media":2047,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[706,810,811,705],"class_list":["post-2038","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sdk","tag-azuresdk","tag-go","tag-golang","tag-sdk"],"acf":[],"blog_post_summary":"<p>This post announces the stable release of the Azure SDK for Go.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/2038","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\/91679"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/comments?post=2038"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/2038\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media\/2047"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media?parent=2038"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/categories?post=2038"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/tags?post=2038"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}