{"id":1964,"date":"2022-04-22T07:40:16","date_gmt":"2022-04-22T14:40:16","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sdk\/?p=1964"},"modified":"2022-05-25T16:41:34","modified_gmt":"2022-05-25T23:41:34","slug":"introducing-the-latest-beta-versions-of-the-azure-sdk-for-go-management-modules","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sdk\/introducing-the-latest-beta-versions-of-the-azure-sdk-for-go-management-modules\/","title":{"rendered":"Introducing the latest beta versions of the Azure SDK for Go management modules"},"content":{"rendered":"<p>You may have heard that Go version 1.18 has been released. This release introduced support for <a href=\"https:\/\/go.dev\/blog\/why-generics\">generic code using parameterized types<\/a>. After applying new language features and learnings from user studies, we&#8217;ve released new beta versions of the Azure SDK for Go management modules. We believe the new versions will provide a better development experience.<\/p>\n<h2>Get the latest modules<\/h2>\n<p>You can get the latest modules using <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\">pkg.go.dev<\/a> or view the latest source code in the <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\">Azure SDK for Go repository<\/a>. You can also find a list of all the management modules with the latest beta version on our <a href=\"https:\/\/azure.github.io\/azure-sdk\/releases\/latest\/mgmt\/go.html\">Azure SDK Releases<\/a> page. Because the new modules apply Go generics, you&#8217;ll need to upgrade to Go 1.18 first.<\/p>\n<h2>API changes<\/h2>\n<h3>Generic poller for long-running operations (LROs)<\/h3>\n<p>We&#8217;ve removed all the non-generic poller response types for all LROs. They&#8217;re replaced with a new generic poller type <code>armruntime.Poller[T]<\/code>. The usage of poller hasn&#8217;t changed much. You can use <code>poller.PollUntilDone<\/code> to get the final response synchronously. Alternatively, you can use <code>poller.Poll<\/code>, <code>poller.Done<\/code>, and <code>poller.Result<\/code> to implement your own polling logic. The following example shows how to use the new poller to get the final result when capturing a virtual machine.<\/p>\n<pre><span class=\"pl-s1\">cred<\/span>, <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">azidentity<\/span>.<span class=\"pl-en\">NewDefaultAzureCredential<\/span>(<span class=\"pl-c1\">nil<\/span>)\r\n<span class=\"pl-k\">if<\/span> <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">!=<\/span> <span class=\"pl-c1\">nil<\/span> {\r\n    <span class=\"pl-en\">panic<\/span>(<span class=\"pl-s1\">err<\/span>)\r\n}\r\n<span class=\"pl-s1\">ctx<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">context<\/span>.<span class=\"pl-en\">TODO<\/span>()\r\n<span class=\"pl-s1\">client<\/span>, <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">armcompute<\/span>.<span class=\"pl-en\">NewVirtualMachinesClient<\/span>(<span class=\"pl-s\">\"&lt;subscription-id&gt;\"<\/span>, <span class=\"pl-s1\">cred<\/span>, <span class=\"pl-c1\">nil<\/span>)\r\n<span class=\"pl-k\">if<\/span> <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">!=<\/span> <span class=\"pl-c1\">nil<\/span> {\r\n    <span class=\"pl-en\">panic<\/span>(<span class=\"pl-s1\">err<\/span>)\r\n}\r\n<span class=\"pl-s1\">poller<\/span>, <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">client<\/span>.<span class=\"pl-en\">BeginCapture<\/span>(<span class=\"pl-s1\">ctx<\/span>,\r\n    <span class=\"pl-s\">\"&lt;resource-group-name&gt;\"<\/span>,\r\n    <span class=\"pl-s\">\"&lt;vm-name&gt;\"<\/span>,\r\n    armcompute.<span class=\"pl-smi\">VirtualMachineCaptureParameters<\/span>{\r\n        <span class=\"pl-c1\">DestinationContainerName<\/span>: <span class=\"pl-s1\">to<\/span>.<span class=\"pl-en\">Ptr<\/span>(<span class=\"pl-s\">\"&lt;destination-container-name&gt;\"<\/span>),\r\n        <span class=\"pl-c1\">OverwriteVhds<\/span>:            <span class=\"pl-s1\">to<\/span>.<span class=\"pl-en\">Ptr<\/span>(<span class=\"pl-c1\">true<\/span>),\r\n        <span class=\"pl-c1\">VhdPrefix<\/span>:                <span class=\"pl-s1\">to<\/span>.<span class=\"pl-en\">Ptr<\/span>(<span class=\"pl-s\">\"&lt;vhd-prefix&gt;\"<\/span>),\r\n    },\r\n    <span class=\"pl-c1\">nil<\/span>)\r\n<span class=\"pl-k\">if<\/span> <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">!=<\/span> <span class=\"pl-c1\">nil<\/span> {\r\n    <span class=\"pl-en\">panic<\/span>(<span class=\"pl-s1\">err<\/span>)\r\n}\r\n<span class=\"pl-s1\">res<\/span>, <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">poller<\/span>.<span class=\"pl-en\">PollUntilDone<\/span>(<span class=\"pl-s1\">ctx<\/span>, <span class=\"pl-c1\">nil<\/span>)\r\n<span class=\"pl-k\">if<\/span> <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">!=<\/span> <span class=\"pl-c1\">nil<\/span> {\r\n    <span class=\"pl-en\">panic<\/span>(<span class=\"pl-s1\">err<\/span>)\r\n}\r\n<span class=\"pl-c\">\/\/ TODO: use response item<\/span>\r\n<span class=\"pl-s1\">_<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">res<\/span><\/pre>\n<h3>Generic pager and new pager API<\/h3>\n<p>As was the case with the generic poller, all the non-generic pager response types for operations with paging result have been removed. They&#8217;re replaced with a new generic pager type <code>runtime.Pager[T]<\/code>. We also simplified the pager API and provided more direct error handling. 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. The following example shows how to use new pager API to list all virtual machines in a resource group.<\/p>\n<pre><span class=\"pl-s1\">cred<\/span>, <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">azidentity<\/span>.<span class=\"pl-en\">NewDefaultAzureCredential<\/span>(<span class=\"pl-c1\">nil<\/span>)\r\n<span class=\"pl-k\">if<\/span> <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">!=<\/span> <span class=\"pl-c1\">nil<\/span> {\r\n    <span class=\"pl-en\">panic<\/span>(<span class=\"pl-s1\">err<\/span>)\r\n}\r\n<span class=\"pl-s1\">ctx<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">context<\/span>.<span class=\"pl-en\">TODO<\/span>()\r\n<span class=\"pl-s1\">client<\/span>, <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">armcompute<\/span>.<span class=\"pl-en\">NewVirtualMachinesClient<\/span>(<span class=\"pl-s\">\"&lt;subscription-id&gt;\"<\/span>, <span class=\"pl-s1\">cred<\/span>, <span class=\"pl-c1\">nil<\/span>)\r\n<span class=\"pl-k\">if<\/span> <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">!=<\/span> <span class=\"pl-c1\">nil<\/span> {\r\n    <span class=\"pl-en\">panic<\/span>(<span class=\"pl-s1\">err<\/span>)\r\n}\r\n<span class=\"pl-s1\">pager<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">client<\/span>.<span class=\"pl-en\">NewListPager<\/span>(<span class=\"pl-s\">\"&lt;resource-group-name&gt;\"<\/span>,\r\n    <span class=\"pl-c1\">&amp;<\/span>armcompute.<span class=\"pl-smi\">VirtualMachinesClientListOptions<\/span>{<span class=\"pl-c1\">Filter<\/span>: <span class=\"pl-s1\">to<\/span>.<span class=\"pl-en\">Ptr<\/span>(<span class=\"pl-s\">\"&lt;filter&gt;\"<\/span>)})\r\n<span class=\"pl-k\">for<\/span> <span class=\"pl-s1\">pager<\/span>.<span class=\"pl-en\">More<\/span>() {\r\n    <span class=\"pl-s1\">nextResult<\/span>, <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">pager<\/span>.<span class=\"pl-en\">NextPage<\/span>(<span class=\"pl-s1\">ctx<\/span>)\r\n    <span class=\"pl-k\">if<\/span> <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">!=<\/span> <span class=\"pl-c1\">nil<\/span> {\r\n        <span class=\"pl-en\">panic<\/span>(<span class=\"pl-s1\">err<\/span>)\r\n    }\r\n    <span class=\"pl-k\">for<\/span> <span class=\"pl-s1\">_<\/span>, <span class=\"pl-s1\">v<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-k\">range<\/span> <span class=\"pl-s1\">nextResult<\/span>.<span class=\"pl-c1\">Value<\/span> {\r\n        <span class=\"pl-c\">\/\/ TODO: use page item<\/span>\r\n        <span class=\"pl-s1\">_<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">v<\/span>\r\n    }\r\n}<\/pre>\n<h3>New pattern to get raw HTTP response<\/h3>\n<p>The response envelope has been simplified for all the operations because a response with deserialized types is sufficient for common scenarios. Previously, you could obtain the raw HTTP response from the response envelope, but now you can get it from the request context instead. The following example shows how to get the raw HTTP response when getting info from a virtual machine.<code class=\"language-go\"><\/code><\/p>\n<pre><span class=\"pl-s1\">cred<\/span>, <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">azidentity<\/span>.<span class=\"pl-en\">NewDefaultAzureCredential<\/span>(<span class=\"pl-c1\">nil<\/span>)\r\n<span class=\"pl-k\">if<\/span> <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">!=<\/span> <span class=\"pl-c1\">nil<\/span> {\r\n    <span class=\"pl-en\">panic<\/span>(<span class=\"pl-s1\">err<\/span>)\r\n}\r\n<span class=\"pl-s1\">client<\/span>, <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">armcompute<\/span>.<span class=\"pl-en\">NewVirtualMachinesClient<\/span>(<span class=\"pl-s\">\"&lt;subscription-id&gt;\"<\/span>, <span class=\"pl-s1\">cred<\/span>, <span class=\"pl-c1\">nil<\/span>)\r\n<span class=\"pl-k\">if<\/span> <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">!=<\/span> <span class=\"pl-c1\">nil<\/span> {\r\n    <span class=\"pl-en\">panic<\/span>(<span class=\"pl-s1\">err<\/span>)\r\n}\r\n<span class=\"pl-k\">var<\/span> <span class=\"pl-s1\">rawResponse<\/span> <span class=\"pl-c1\">*<\/span>http.<span class=\"pl-smi\">Response<\/span>\r\n<span class=\"pl-s1\">ctx<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">context<\/span>.<span class=\"pl-en\">TODO<\/span>()\r\n<span class=\"pl-s1\">ctxWithResp<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">runtime<\/span>.<span class=\"pl-en\">WithCaptureResponse<\/span>(<span class=\"pl-s1\">ctx<\/span>, <span class=\"pl-c1\">&amp;<\/span><span class=\"pl-s1\">rawResponse<\/span>)\r\n<span class=\"pl-s1\">res<\/span>, <span class=\"pl-s1\">err<\/span> <span class=\"pl-c1\">:=<\/span> <span class=\"pl-s1\">client<\/span>.<span class=\"pl-en\">Get<\/span>(<span class=\"pl-s1\">ctxWithResp<\/span>,\r\n    <span class=\"pl-s\">\"&lt;resource-group-name&gt;\"<\/span>,\r\n    <span class=\"pl-s\">\"&lt;vm-name&gt;\"<\/span>,\r\n    <span class=\"pl-c1\">nil<\/span>)\r\n<span class=\"pl-c\">\/\/ TODO: use raw response<\/span>\r\n<span class=\"pl-s1\">_<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">rawResponse<\/span>.<span class=\"pl-c1\">Body<\/span><\/pre>\n<h3>Generic pointer conversion helper<\/h3>\n<p>The new version provides generic <code>to.Ptr[T]<\/code> and <code>to.SliceOfPtrs[T]<\/code> for pointer conversion and removes all non-generic implementations.<\/p>\n<pre><code class=\"language-go\">int32Pointer := to.Ptr[int32](2)\r\nintPointer := to.Ptr(3)\r\nstringPointer := to.Ptr(\"test\")\r\nintSlicePointer := to.SliceOfPtrs([]int{1, 2, 3})<\/code><\/pre>\n<h2>Conclusion<\/h2>\n<p>In these new beta modules, we reduced the number of top-level symbols and provide simplified APIs for operations. We&#8217;ll continue to add samples and docs to familiarize developers with the latest management modules. The stable versions of the Azure SDK for Go management modules are coming soon.<\/p>\n<h2>Feedback<\/h2>\n<p>We encourage you to upgrade to these new beta versions and always welcome your feedback. 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. For more information on how we triage issues, see <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>You may have heard that Go version 1.18 has been released. This release introduced support for generic code using parameterized types. After applying new language features and learnings from user studies, we&#8217;ve released new beta versions of the Azure SDK for Go management modules. We believe the new versions will provide a better development experience. [&hellip;]<\/p>\n","protected":false},"author":88503,"featured_media":1970,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[750,706,810,811,807],"class_list":["post-1964","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sdk","tag-azure-sdk","tag-azuresdk","tag-go","tag-golang","tag-management-libraries"],"acf":[],"blog_post_summary":"<p>You may have heard that Go version 1.18 has been released. This release introduced support for generic code using parameterized types. After applying new language features and learnings from user studies, we&#8217;ve released new beta versions of the Azure SDK for Go management modules. We believe the new versions will provide a better development experience. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/1964","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\/88503"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/comments?post=1964"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/1964\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media\/1970"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media?parent=1964"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/categories?post=1964"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/tags?post=1964"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}